@1001-digital/components.evm 1.3.1 → 2.0.1
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 +2 -2
- package/src/client-only.ts +1 -0
- package/src/components/EvmConnect.vue +3 -3
- package/src/components/EvmConnectorQR.vue +1 -1
- package/src/components/EvmInAppWalletSetup.vue +5 -5
- package/src/components/EvmMetaMaskQR.vue +1 -1
- package/src/components/EvmProfile.vue +3 -3
- package/src/components/EvmTransactionFlow.vue +43 -29
- package/src/components/EvmWalletConnectWallets.vue +2 -2
- package/src/composables/gasPrice.ts +11 -6
- package/src/composables/priceFeed.ts +4 -3
- package/src/composables/siwe.ts +4 -0
- package/src/utils/cache.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1001-digital/components.evm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"*.css"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@wagmi/vue": ">=0.5.0",
|
|
19
19
|
"viem": ">=2.0.0",
|
|
20
20
|
"vue": "^3.5.0",
|
|
21
|
-
"@1001-digital/components": "^
|
|
21
|
+
"@1001-digital/components": "^2.0.1"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@1001-digital/dweb-fetch": "^0.1.6",
|
package/src/client-only.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
class="link muted small"
|
|
13
13
|
@click="resetConnection"
|
|
14
14
|
>
|
|
15
|
-
<Icon
|
|
15
|
+
<Icon name="chevron-left" />
|
|
16
16
|
<span>Back</span>
|
|
17
17
|
</Button>
|
|
18
18
|
</template>
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
v-else
|
|
53
53
|
class="default-wallet-icon"
|
|
54
54
|
>
|
|
55
|
-
<Icon
|
|
55
|
+
<Icon name="wallet" />
|
|
56
56
|
</div>
|
|
57
57
|
<span>{{ connector.name }}</span>
|
|
58
58
|
</Button>
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
target="_blank"
|
|
84
84
|
class="link muted small"
|
|
85
85
|
>
|
|
86
|
-
<Icon
|
|
86
|
+
<Icon name="help" />
|
|
87
87
|
<span>New to wallets?</span>
|
|
88
88
|
</Button>
|
|
89
89
|
</div>
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
class="block"
|
|
13
13
|
@click="startGenerate"
|
|
14
14
|
>
|
|
15
|
-
<Icon
|
|
15
|
+
<Icon name="plus" />
|
|
16
16
|
<span>Create New Wallet</span>
|
|
17
17
|
</Button>
|
|
18
18
|
<Button
|
|
19
19
|
class="block"
|
|
20
20
|
@click="step = 'restore'"
|
|
21
21
|
>
|
|
22
|
-
<Icon
|
|
22
|
+
<Icon name="key" />
|
|
23
23
|
<span>Use Existing Recovery Key</span>
|
|
24
24
|
</Button>
|
|
25
25
|
</div>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
class="link muted small"
|
|
28
28
|
@click="$emit('back')"
|
|
29
29
|
>
|
|
30
|
-
<Icon
|
|
30
|
+
<Icon name="chevron-left" />
|
|
31
31
|
<span>Back</span>
|
|
32
32
|
</Button>
|
|
33
33
|
</div>
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
class="link muted small"
|
|
72
72
|
@click="step = 'choose'"
|
|
73
73
|
>
|
|
74
|
-
<Icon
|
|
74
|
+
<Icon name="chevron-left" />
|
|
75
75
|
<span>Back</span>
|
|
76
76
|
</Button>
|
|
77
77
|
</div>
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
class="link muted small"
|
|
103
103
|
@click="step = 'choose'"
|
|
104
104
|
>
|
|
105
|
-
<Icon
|
|
105
|
+
<Icon name="chevron-left" />
|
|
106
106
|
<span>Back</span>
|
|
107
107
|
</Button>
|
|
108
108
|
</div>
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
@click="copyAddress"
|
|
42
42
|
>
|
|
43
43
|
<span>{{ shortAddr }}</span>
|
|
44
|
-
<Icon :
|
|
44
|
+
<Icon :name="copied ? 'check' : 'copy'" />
|
|
45
45
|
</Button>
|
|
46
46
|
</div>
|
|
47
47
|
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<EvmSwitchNetwork class-name="block">
|
|
52
52
|
<template #default="{ currentChain }">
|
|
53
|
-
<Icon
|
|
53
|
+
<Icon name="wallet" />
|
|
54
54
|
<span>Switch Network ({{ currentChain?.name || 'Unknown' }})</span>
|
|
55
55
|
</template>
|
|
56
56
|
</EvmSwitchNetwork>
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
:to="`https://app.ens.domains/${ensName}`"
|
|
62
62
|
target="_blank"
|
|
63
63
|
>
|
|
64
|
-
<Icon
|
|
64
|
+
<Icon name="link" />
|
|
65
65
|
<span>Manage ENS</span>
|
|
66
66
|
</Button>
|
|
67
67
|
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
v-if="step === 'requesting'"
|
|
21
21
|
spinner
|
|
22
22
|
stacked
|
|
23
|
-
:txt="
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
:txt="
|
|
24
|
+
connector?.name
|
|
25
|
+
? `Requesting signature from ${connector.name}...`
|
|
26
|
+
: text.lead[step] || ''
|
|
27
|
+
"
|
|
26
28
|
/>
|
|
27
29
|
|
|
28
30
|
<p v-if="step !== 'requesting' && step !== 'error' && text.lead[step]">
|
|
@@ -78,9 +80,20 @@ import { ref, computed, watch, onBeforeUnmount } from 'vue'
|
|
|
78
80
|
import { waitForTransactionReceipt, watchChainId } from '@wagmi/core'
|
|
79
81
|
import { useConfig, useConnection, type Config } from '@wagmi/vue'
|
|
80
82
|
import type { TransactionReceipt, Hash } from 'viem'
|
|
81
|
-
import {
|
|
83
|
+
import {
|
|
84
|
+
Dialog,
|
|
85
|
+
Loading,
|
|
86
|
+
Alert,
|
|
87
|
+
Button,
|
|
88
|
+
useToast,
|
|
89
|
+
delay,
|
|
90
|
+
} from '@1001-digital/components'
|
|
82
91
|
import { useEnsureChainIdCheck, useBlockExplorer } from '../composables/chainId'
|
|
83
|
-
import type {
|
|
92
|
+
import type {
|
|
93
|
+
TransactionFlowText,
|
|
94
|
+
EvmTransactionFlowProps,
|
|
95
|
+
EvmTransactionFlowEmits,
|
|
96
|
+
} from '../types'
|
|
84
97
|
|
|
85
98
|
type Step =
|
|
86
99
|
| 'idle'
|
|
@@ -113,16 +126,13 @@ const defaultText = {
|
|
|
113
126
|
},
|
|
114
127
|
} satisfies TransactionFlowText
|
|
115
128
|
|
|
116
|
-
const props = withDefaults(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
dismissable: true,
|
|
124
|
-
},
|
|
125
|
-
)
|
|
129
|
+
const props = withDefaults(defineProps<EvmTransactionFlowProps>(), {
|
|
130
|
+
delayAfter: 2000,
|
|
131
|
+
delayAutoclose: 2000,
|
|
132
|
+
skipConfirmation: false,
|
|
133
|
+
autoCloseSuccess: true,
|
|
134
|
+
dismissable: true,
|
|
135
|
+
})
|
|
126
136
|
|
|
127
137
|
function isUserRejection(e: unknown): boolean {
|
|
128
138
|
const re = /reject|denied|cancel/i
|
|
@@ -246,7 +256,9 @@ const initializeRequest = async (request = cachedRequest.value) => {
|
|
|
246
256
|
const start = Date.now()
|
|
247
257
|
progressTimer = setInterval(() => {
|
|
248
258
|
const elapsed = (Date.now() - start) / 1000
|
|
249
|
-
toast.update(toastId, {
|
|
259
|
+
toast.update(toastId, {
|
|
260
|
+
progress: Math.round(90 * (1 - Math.exp(-elapsed / 15))),
|
|
261
|
+
})
|
|
250
262
|
}, 500)
|
|
251
263
|
|
|
252
264
|
try {
|
|
@@ -309,22 +321,24 @@ defineExpose({
|
|
|
309
321
|
})
|
|
310
322
|
</script>
|
|
311
323
|
|
|
312
|
-
<style>
|
|
313
|
-
.transaction-flow
|
|
314
|
-
|
|
315
|
-
|
|
324
|
+
<style scoped>
|
|
325
|
+
.transaction-flow {
|
|
326
|
+
&:deep(> section) {
|
|
327
|
+
display: grid;
|
|
328
|
+
gap: var(--spacer);
|
|
316
329
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
330
|
+
.text {
|
|
331
|
+
width: 100%;
|
|
332
|
+
height: min-content;
|
|
333
|
+
}
|
|
321
334
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
335
|
+
p {
|
|
336
|
+
white-space: pre-wrap;
|
|
337
|
+
width: 100%;
|
|
325
338
|
|
|
326
|
-
|
|
327
|
-
|
|
339
|
+
a {
|
|
340
|
+
text-decoration: underline;
|
|
341
|
+
}
|
|
328
342
|
}
|
|
329
343
|
}
|
|
330
344
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<FormItem>
|
|
12
12
|
<template #prefix>
|
|
13
|
-
<Icon
|
|
13
|
+
<Icon name="lucide:search" />
|
|
14
14
|
</template>
|
|
15
15
|
<input
|
|
16
16
|
v-model="searchQuery"
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
class="link muted small"
|
|
62
62
|
@click="$emit('back')"
|
|
63
63
|
>
|
|
64
|
-
<Icon
|
|
64
|
+
<Icon name="chevron-left" />
|
|
65
65
|
<span>Back</span>
|
|
66
66
|
</Button>
|
|
67
67
|
</div>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ref, computed, watch,
|
|
1
|
+
import { ref, computed, watch, onScopeDispose, type Ref } from 'vue'
|
|
2
2
|
import { formatEther, formatGwei } from 'viem'
|
|
3
3
|
import { getGasPrice } from '@wagmi/core'
|
|
4
4
|
import { useConfig, useBlockNumber } from '@wagmi/vue'
|
|
5
5
|
|
|
6
|
-
let priceWatcher: WatchStopHandle | null = null
|
|
7
6
|
const price: Ref<bigint> = ref(0n)
|
|
7
|
+
let watcherCount = 0
|
|
8
8
|
|
|
9
9
|
export const useGasPrice = () => {
|
|
10
10
|
const config = useConfig()
|
|
@@ -14,10 +14,15 @@ export const useGasPrice = () => {
|
|
|
14
14
|
price.value = await getGasPrice(config)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
if (watcherCount === 0) updatePrice()
|
|
18
|
+
watcherCount++
|
|
19
|
+
|
|
20
|
+
const stopWatcher = watch(blockNumber, () => updatePrice())
|
|
21
|
+
|
|
22
|
+
onScopeDispose(() => {
|
|
23
|
+
stopWatcher()
|
|
24
|
+
watcherCount--
|
|
25
|
+
})
|
|
21
26
|
|
|
22
27
|
const unitPrice = computed(() => ({
|
|
23
28
|
wei: price.value,
|
|
@@ -74,11 +74,12 @@ export const usePriceFeed = () => {
|
|
|
74
74
|
const ethUSD = computed(() =>
|
|
75
75
|
state.ethUSDRaw ? state.ethUSDRaw / BigInt(1e8) : 0n,
|
|
76
76
|
)
|
|
77
|
-
|
|
77
|
+
// Chainlink returns 8 decimals; dividing by 1e6 keeps 2 decimal digits (cents)
|
|
78
|
+
const ethUSDCents = computed(() =>
|
|
78
79
|
state.ethUSDRaw ? state.ethUSDRaw / BigInt(1e6) : 0n,
|
|
79
80
|
)
|
|
80
81
|
const ethUSDFormatted = computed(() =>
|
|
81
|
-
formatPrice(Number(
|
|
82
|
+
formatPrice(Number(ethUSDCents.value) / 100, 2),
|
|
82
83
|
)
|
|
83
84
|
|
|
84
85
|
const weiToUSD = (wei: bigint) => {
|
|
@@ -108,7 +109,7 @@ export const usePriceFeed = () => {
|
|
|
108
109
|
return {
|
|
109
110
|
ethUSDRaw: computed(() => state.ethUSDRaw),
|
|
110
111
|
ethUSD,
|
|
111
|
-
|
|
112
|
+
ethUSDCents,
|
|
112
113
|
ethUSDFormatted,
|
|
113
114
|
weiToUSD,
|
|
114
115
|
fetchPrice,
|
package/src/composables/siwe.ts
CHANGED
|
@@ -47,6 +47,10 @@ export const useSiwe = () => {
|
|
|
47
47
|
|
|
48
48
|
const nonce = await options.getNonce()
|
|
49
49
|
|
|
50
|
+
if (typeof window === 'undefined') {
|
|
51
|
+
throw new Error('SIWE sign-in requires a browser environment')
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
const messageParams: SiweMessageParams = {
|
|
51
55
|
domain: options.domain || window.location.host,
|
|
52
56
|
address: currentAddress,
|