@1001-digital/components 1.2.2 → 1.3.0

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.
Files changed (48) hide show
  1. package/package.json +2 -22
  2. package/src/base/components/AppShell.vue +60 -0
  3. package/src/base/components/BottomNav.vue +44 -0
  4. package/src/base/components/Sidebar.vue +282 -0
  5. package/src/index.ts +3 -3
  6. package/src/evm/assets/wallets/coinbase.svg +0 -4
  7. package/src/evm/assets/wallets/in-app.svg +0 -5
  8. package/src/evm/assets/wallets/metamask.svg +0 -1
  9. package/src/evm/assets/wallets/phantom.svg +0 -4
  10. package/src/evm/assets/wallets/rabby.svg +0 -24
  11. package/src/evm/assets/wallets/rainbow.svg +0 -59
  12. package/src/evm/assets/wallets/safe.png +0 -0
  13. package/src/evm/assets/wallets/walletconnect.svg +0 -1
  14. package/src/evm/components/EvmAccount.vue +0 -28
  15. package/src/evm/components/EvmAvatar.vue +0 -62
  16. package/src/evm/components/EvmConnect.vue +0 -303
  17. package/src/evm/components/EvmConnectDialog.vue +0 -75
  18. package/src/evm/components/EvmConnectionStatus.vue +0 -13
  19. package/src/evm/components/EvmConnectorQR.vue +0 -86
  20. package/src/evm/components/EvmInAppWalletSetup.vue +0 -251
  21. package/src/evm/components/EvmMetaMaskQR.vue +0 -34
  22. package/src/evm/components/EvmProfile.vue +0 -186
  23. package/src/evm/components/EvmSeedPhraseInput.vue +0 -193
  24. package/src/evm/components/EvmSiwe.vue +0 -190
  25. package/src/evm/components/EvmSiweDialog.vue +0 -93
  26. package/src/evm/components/EvmSwitchNetwork.vue +0 -132
  27. package/src/evm/components/EvmTransactionFlow.vue +0 -353
  28. package/src/evm/components/EvmWalletConnectQR.vue +0 -13
  29. package/src/evm/components/EvmWalletConnectWallets.vue +0 -200
  30. package/src/evm/composables/base.ts +0 -7
  31. package/src/evm/composables/chainId.ts +0 -42
  32. package/src/evm/composables/ens.ts +0 -113
  33. package/src/evm/composables/gasPrice.ts +0 -37
  34. package/src/evm/composables/priceFeed.ts +0 -116
  35. package/src/evm/composables/siwe.ts +0 -89
  36. package/src/evm/composables/uri.ts +0 -12
  37. package/src/evm/composables/walletExplorer.ts +0 -130
  38. package/src/evm/config.ts +0 -35
  39. package/src/evm/connectors/inAppWallet.ts +0 -5
  40. package/src/evm/index.ts +0 -60
  41. package/src/evm/utils/addresses.ts +0 -6
  42. package/src/evm/utils/cache.ts +0 -59
  43. package/src/evm/utils/chains.ts +0 -32
  44. package/src/evm/utils/ens.ts +0 -116
  45. package/src/evm/utils/format-eth.ts +0 -15
  46. package/src/evm/utils/price.ts +0 -17
  47. package/src/evm/utils/siwe.ts +0 -70
  48. package/src/evm/utils/uri.ts +0 -24
@@ -1,113 +0,0 @@
1
- import { ref, computed, watchEffect, toValue, type MaybeRefOrGetter, type Ref } from 'vue'
2
- import { getPublicClient } from '@wagmi/core'
3
- import { useConfig, type Config } from '@wagmi/vue'
4
- import { useEvmConfig } from '../config'
5
- import {
6
- ensCache,
7
- fetchEnsFromIndexer,
8
- fetchEnsFromChain,
9
- ENS_KEYS_AVATAR,
10
- ENS_KEYS_PROFILE,
11
- } from '../utils/ens'
12
- import type { EnsProfile } from '../utils/ens'
13
-
14
- type EnsMode = 'indexer' | 'chain'
15
-
16
- interface UseEnsOptions {
17
- mode?: MaybeRefOrGetter<EnsMode | undefined>
18
- }
19
-
20
- async function resolve(
21
- identifier: string,
22
- strategies: EnsMode[],
23
- indexerUrls: string[],
24
- wagmi: Config,
25
- chainKeys: string[],
26
- ): Promise<EnsProfile> {
27
- for (const strategy of strategies) {
28
- try {
29
- if (strategy === 'indexer') {
30
- if (!indexerUrls.length) continue
31
- return await fetchEnsFromIndexer(identifier, indexerUrls)
32
- }
33
-
34
- if (strategy === 'chain') {
35
- const client = getPublicClient(wagmi, { chainId: 1 })
36
- if (!client) continue
37
- return await fetchEnsFromChain(identifier, client, chainKeys)
38
- }
39
- } catch {
40
- continue
41
- }
42
- }
43
-
44
- return { address: identifier, ens: null, data: null }
45
- }
46
-
47
- function useEnsBase(
48
- tier: string,
49
- identifier: MaybeRefOrGetter<string | undefined>,
50
- chainKeys: string[],
51
- options: UseEnsOptions = {},
52
- ) {
53
- const config = useConfig()
54
- const evmConfig = useEvmConfig()
55
-
56
- const mode = computed<EnsMode>(
57
- () => toValue(options.mode) || evmConfig.ens?.mode || 'indexer',
58
- )
59
- const indexerUrls = computed(() => evmConfig.ens?.indexerUrls || [])
60
- const cacheKey = computed(() => `ens-${tier}-${toValue(identifier)}`)
61
-
62
- const data: Ref<EnsProfile | null | undefined> = ref(
63
- ensCache.get(cacheKey.value) ?? undefined,
64
- )
65
- const pending = ref(false)
66
-
67
- watchEffect(async () => {
68
- const id = toValue(identifier)
69
- if (!id) {
70
- data.value = null
71
- pending.value = false
72
- return
73
- }
74
-
75
- const cached = ensCache.get(cacheKey.value)
76
- if (cached) {
77
- data.value = cached
78
- pending.value = false
79
- return
80
- }
81
-
82
- const strategies: EnsMode[] =
83
- mode.value === 'indexer' ? ['indexer', 'chain'] : ['chain', 'indexer']
84
-
85
- pending.value = true
86
- try {
87
- data.value = await ensCache.fetch(cacheKey.value, () =>
88
- resolve(id, strategies, indexerUrls.value, config, chainKeys),
89
- )
90
- } catch {
91
- data.value = null
92
- } finally {
93
- pending.value = false
94
- }
95
- })
96
-
97
- return { data, pending }
98
- }
99
-
100
- export const useEns = (
101
- identifier: MaybeRefOrGetter<string | undefined>,
102
- options?: UseEnsOptions,
103
- ) => useEnsBase('resolve', identifier, [], options)
104
-
105
- export const useEnsWithAvatar = (
106
- identifier: MaybeRefOrGetter<string | undefined>,
107
- options?: UseEnsOptions,
108
- ) => useEnsBase('avatar', identifier, [...ENS_KEYS_AVATAR], options)
109
-
110
- export const useEnsProfile = (
111
- identifier: MaybeRefOrGetter<string | undefined>,
112
- options?: UseEnsOptions,
113
- ) => useEnsBase('profile', identifier, [...ENS_KEYS_PROFILE], options)
@@ -1,37 +0,0 @@
1
- import { ref, computed, watch, type Ref, type WatchStopHandle } from 'vue'
2
- import { formatEther, formatGwei } from 'viem'
3
- import { getGasPrice } from '@wagmi/core'
4
- import { useConfig, useBlockNumber } from '@wagmi/vue'
5
-
6
- let priceWatcher: WatchStopHandle | null = null
7
- const price: Ref<bigint> = ref(0n)
8
-
9
- export const useGasPrice = () => {
10
- const config = useConfig()
11
- const { data: blockNumber } = useBlockNumber()
12
-
13
- const updatePrice = async () => {
14
- price.value = await getGasPrice(config)
15
- }
16
-
17
- if (!priceWatcher) {
18
- updatePrice()
19
- priceWatcher = watch(blockNumber, () => updatePrice())
20
- }
21
-
22
- const unitPrice = computed(() => ({
23
- wei: price.value,
24
- gwei: formatGwei(price.value),
25
- eth: formatEther(price.value),
26
-
27
- formatted: {
28
- gwei:
29
- price.value > 2_000_000_000_000n
30
- ? Math.round(parseFloat(formatGwei(price.value)))
31
- : parseFloat(formatGwei(price.value)).toFixed(1),
32
- eth: formatEther(price.value),
33
- },
34
- }))
35
-
36
- return unitPrice
37
- }
@@ -1,116 +0,0 @@
1
- import { reactive, computed } from 'vue'
2
- import { readContract } from '@wagmi/core'
3
- import { useConfig } from '@wagmi/vue'
4
- import { parseJSON, stringifyJSON, formatPrice } from '../utils/price'
5
- import { nowInSeconds } from '../../base/utils/time'
6
-
7
- const CHAINLINK_ETH_USD_ABI = [
8
- {
9
- inputs: [],
10
- name: 'latestRoundData',
11
- outputs: [
12
- { internalType: 'uint80', name: 'roundId', type: 'uint80' },
13
- { internalType: 'int256', name: 'answer', type: 'int256' },
14
- { internalType: 'uint256', name: 'startedAt', type: 'uint256' },
15
- { internalType: 'uint256', name: 'updatedAt', type: 'uint256' },
16
- { internalType: 'uint80', name: 'answeredInRound', type: 'uint80' },
17
- ],
18
- stateMutability: 'view',
19
- type: 'function',
20
- },
21
- ] as const
22
-
23
- const CHAINLINK_ETH_USD = '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'
24
- const STORAGE_KEY = 'evm:price-feed'
25
- const CACHE_TTL = 3_600 // 1 hour in seconds
26
-
27
- interface PriceFeedState {
28
- ethUSDRaw: bigint | null
29
- lastUpdated: number
30
- }
31
-
32
- const state = reactive<PriceFeedState>({
33
- ethUSDRaw: null,
34
- lastUpdated: 0,
35
- })
36
-
37
- function loadFromStorage() {
38
- if (typeof window === 'undefined') return
39
-
40
- try {
41
- const stored = localStorage.getItem(STORAGE_KEY)
42
- if (!stored) return
43
-
44
- const parsed = parseJSON(stored) as PriceFeedState
45
- if (parsed.ethUSDRaw) state.ethUSDRaw = parsed.ethUSDRaw
46
- if (parsed.lastUpdated) state.lastUpdated = parsed.lastUpdated
47
- } catch {
48
- // Ignore corrupted storage
49
- }
50
- }
51
-
52
- function saveToStorage() {
53
- if (typeof window === 'undefined') return
54
-
55
- try {
56
- localStorage.setItem(
57
- STORAGE_KEY,
58
- stringifyJSON({
59
- ethUSDRaw: state.ethUSDRaw,
60
- lastUpdated: state.lastUpdated,
61
- }),
62
- )
63
- } catch {
64
- // Ignore storage errors
65
- }
66
- }
67
-
68
- export const usePriceFeed = () => {
69
- const config = useConfig()
70
-
71
- // Load cached data on first use
72
- if (!state.lastUpdated) loadFromStorage()
73
-
74
- const ethUSD = computed(() =>
75
- state.ethUSDRaw ? state.ethUSDRaw / BigInt(1e8) : 0n,
76
- )
77
- const ethUSC = computed(() =>
78
- state.ethUSDRaw ? state.ethUSDRaw / BigInt(1e6) : 0n,
79
- )
80
- const ethUSDFormatted = computed(() =>
81
- formatPrice(Number(ethUSC.value) / 100, 2),
82
- )
83
-
84
- const weiToUSD = (wei: bigint) => {
85
- const cents = (wei * (state.ethUSDRaw || 0n)) / 10n ** 18n / 10n ** 6n
86
- return formatPrice(Number(cents) / 100, 2)
87
- }
88
-
89
- async function fetchPrice() {
90
- if (nowInSeconds() - state.lastUpdated < CACHE_TTL) return
91
-
92
- try {
93
- const [, answer] = await readContract(config, {
94
- address: CHAINLINK_ETH_USD,
95
- abi: CHAINLINK_ETH_USD_ABI,
96
- functionName: 'latestRoundData',
97
- chainId: 1,
98
- })
99
-
100
- state.ethUSDRaw = answer
101
- state.lastUpdated = nowInSeconds()
102
- saveToStorage()
103
- } catch (error) {
104
- console.warn('Error fetching ETH/USD price:', error)
105
- }
106
- }
107
-
108
- return {
109
- ethUSDRaw: computed(() => state.ethUSDRaw),
110
- ethUSD,
111
- ethUSC,
112
- ethUSDFormatted,
113
- weiToUSD,
114
- fetchPrice,
115
- }
116
- }
@@ -1,89 +0,0 @@
1
- import { ref, readonly } from 'vue'
2
- import { signMessage } from '@wagmi/core'
3
- import { useConfig, useConnection } from '@wagmi/vue'
4
- import type { Config } from '@wagmi/vue'
5
- import { createSiweMessage, type SiweMessageParams } from '../utils/siwe'
6
-
7
- export interface SiweSession {
8
- address: `0x${string}`
9
- chainId: number
10
- }
11
-
12
- export interface UseSiweOptions {
13
- getNonce: () => Promise<string>
14
- verify: (message: string, signature: string) => Promise<boolean>
15
- domain?: string
16
- uri?: string
17
- statement?: string
18
- expirationTime?: string
19
- requestId?: string
20
- resources?: string[]
21
- }
22
-
23
- const _isAuthenticated = ref(false)
24
- const _session = ref<SiweSession | null>(null)
25
-
26
- export const useSiwe = () => {
27
- const config = useConfig()
28
- const { address, chainId } = useConnection()
29
-
30
- const setSession = (session: SiweSession) => {
31
- _isAuthenticated.value = true
32
- _session.value = session
33
- }
34
-
35
- const clearSession = () => {
36
- _isAuthenticated.value = false
37
- _session.value = null
38
- }
39
-
40
- const signIn = async (options: UseSiweOptions) => {
41
- const currentAddress = address.value
42
- const currentChainId = chainId.value
43
-
44
- if (!currentAddress || !currentChainId) {
45
- throw new Error('Wallet not connected')
46
- }
47
-
48
- const nonce = await options.getNonce()
49
-
50
- const messageParams: SiweMessageParams = {
51
- domain: options.domain || window.location.host,
52
- address: currentAddress,
53
- uri: options.uri || window.location.origin,
54
- chainId: currentChainId,
55
- nonce,
56
- statement: options.statement,
57
- expirationTime: options.expirationTime,
58
- requestId: options.requestId,
59
- resources: options.resources,
60
- }
61
-
62
- const message = createSiweMessage(messageParams)
63
- const signature = await signMessage(config as Config, { message })
64
-
65
- const verified = await options.verify(message, signature)
66
-
67
- if (!verified) {
68
- throw new Error('Signature verification failed')
69
- }
70
-
71
- setSession({
72
- address: currentAddress,
73
- chainId: currentChainId,
74
- })
75
- }
76
-
77
- const signOut = () => {
78
- clearSession()
79
- }
80
-
81
- return {
82
- isAuthenticated: readonly(_isAuthenticated),
83
- session: readonly(_session),
84
- signIn,
85
- signOut,
86
- setSession,
87
- clearSession,
88
- }
89
- }
@@ -1,12 +0,0 @@
1
- import { useEvmConfig } from '../config'
2
- import { resolveUri } from '../utils/uri'
3
-
4
- export const useResolveUri = () => {
5
- const evmConfig = useEvmConfig()
6
-
7
- return (uri?: string) =>
8
- resolveUri(uri, {
9
- ipfsGateway: evmConfig.ipfsGateway,
10
- arweaveGateway: evmConfig.arweaveGateway,
11
- })
12
- }
@@ -1,130 +0,0 @@
1
- import { ref, computed } from 'vue'
2
- import { useEvmConfig } from '../config'
3
-
4
- const EXPLORER_API = 'https://explorer-api.walletconnect.com/v3'
5
- const RECENT_KEY = 'evm:recent-wallets'
6
- const PAGE_SIZE = 40
7
-
8
- export interface ExplorerWallet {
9
- id: string
10
- name: string
11
- image_id: string
12
- homepage: string
13
- mobile: { native: string; universal: string }
14
- desktop: { native: string; universal: string }
15
- injected: { namespace: string; injected_id: string }[] | null
16
- }
17
-
18
- export function useWalletExplorer() {
19
- const config = useEvmConfig()
20
- const projectId = computed(() => config.walletConnectProjectId || '')
21
-
22
- const wallets = ref<ExplorerWallet[]>([])
23
- const searchResults = ref<ExplorerWallet[]>([])
24
- const totalCount = ref(0)
25
- const page = ref(0)
26
- const loading = ref(false)
27
- const searching = ref(false)
28
- const recentIds = ref<string[]>(loadRecent())
29
-
30
- const recentWallets = computed(() =>
31
- recentIds.value
32
- .map(id => wallets.value.find(w => w.id === id))
33
- .filter((w): w is ExplorerWallet => !!w)
34
- )
35
-
36
- const hasMore = computed(() => wallets.value.length < totalCount.value)
37
-
38
- function imageUrl(wallet: ExplorerWallet) {
39
- return `${EXPLORER_API}/logo/md/${wallet.image_id}?projectId=${projectId.value}`
40
- }
41
-
42
- function walletHref(wallet: ExplorerWallet, uri: string) {
43
- const encoded = encodeURIComponent(uri)
44
-
45
- const universal = wallet.mobile?.universal
46
- if (universal) {
47
- const base = universal.endsWith('/') ? universal : universal + '/'
48
- return `${base}wc?uri=${encoded}`
49
- }
50
-
51
- const native = wallet.mobile?.native
52
- if (native) {
53
- return `${native}wc?uri=${encoded}`
54
- }
55
-
56
- return null
57
- }
58
-
59
- async function fetchNextPage() {
60
- if (!projectId.value || loading.value) return
61
- loading.value = true
62
- const nextPage = page.value + 1
63
- try {
64
- const res = await fetch(
65
- `${EXPLORER_API}/wallets?projectId=${projectId.value}&entries=${PAGE_SIZE}&page=${nextPage}&sdks=sign_v2`
66
- )
67
- const data = await res.json()
68
- const fetched = Object.values(data.listings || {}) as ExplorerWallet[]
69
- wallets.value = nextPage === 1 ? fetched : [...wallets.value, ...fetched]
70
- totalCount.value = data.total || 0
71
- page.value = nextPage
72
- } catch (e) {
73
- console.error('Failed to fetch wallets:', e)
74
- } finally {
75
- loading.value = false
76
- }
77
- }
78
-
79
- async function search(query: string) {
80
- if (!projectId.value || !query || query.length < 2) {
81
- searchResults.value = []
82
- return
83
- }
84
- searching.value = true
85
- try {
86
- const res = await fetch(
87
- `${EXPLORER_API}/wallets?projectId=${projectId.value}&entries=${PAGE_SIZE}&page=1&search=${encodeURIComponent(query)}&sdks=sign_v2`
88
- )
89
- const data = await res.json()
90
- searchResults.value = Object.values(data.listings || {})
91
- } catch (e) {
92
- console.error('Failed to search wallets:', e)
93
- } finally {
94
- searching.value = false
95
- }
96
- }
97
-
98
- function loadRecent(): string[] {
99
- try {
100
- return JSON.parse(localStorage.getItem(RECENT_KEY) || '[]')
101
- } catch {
102
- return []
103
- }
104
- }
105
-
106
- function addRecent(walletId: string) {
107
- const ids = recentIds.value.filter(id => id !== walletId)
108
- ids.unshift(walletId)
109
- recentIds.value = ids.slice(0, 3)
110
- try {
111
- localStorage.setItem(RECENT_KEY, JSON.stringify(recentIds.value))
112
- } catch {}
113
- }
114
-
115
- return {
116
- wallets,
117
- searchResults,
118
- totalCount,
119
- page,
120
- loading,
121
- searching,
122
- recentWallets,
123
- hasMore,
124
- imageUrl,
125
- walletHref,
126
- fetchNextPage,
127
- search,
128
- addRecent,
129
- }
130
- }
package/src/evm/config.ts DELETED
@@ -1,35 +0,0 @@
1
- import { inject, type InjectionKey } from 'vue'
2
-
3
- export interface EvmChainConfig {
4
- id: number
5
- blockExplorer?: string
6
- }
7
-
8
- export interface EvmConfig {
9
- title?: string
10
- defaultChain?: string
11
- chains: Record<string, EvmChainConfig>
12
- ens?: {
13
- mode?: 'indexer' | 'chain'
14
- indexerUrls?: string[]
15
- }
16
- ipfsGateway?: string
17
- arweaveGateway?: string
18
- baseURL?: string
19
- walletConnectProjectId?: string
20
- }
21
-
22
- export const EvmConfigKey: InjectionKey<EvmConfig> = Symbol('EvmConfig')
23
-
24
- export const defaultEvmConfig: EvmConfig = {
25
- title: 'EVM Layer',
26
- defaultChain: 'mainnet',
27
- chains: {
28
- mainnet: { id: 1, blockExplorer: 'https://etherscan.io' },
29
- },
30
- ens: { mode: 'indexer' },
31
- }
32
-
33
- export const useEvmConfig = (): EvmConfig => {
34
- return inject(EvmConfigKey, defaultEvmConfig)
35
- }
@@ -1,5 +0,0 @@
1
- export {
2
- inAppWallet,
3
- prepareInAppWallet,
4
- type InAppWalletParameters,
5
- } from '@1001-digital/wagmi-in-app-wallet'
package/src/evm/index.ts DELETED
@@ -1,60 +0,0 @@
1
- // Config
2
- export { EvmConfigKey, defaultEvmConfig, useEvmConfig } from './config'
3
- export type { EvmConfig, EvmChainConfig } from './config'
4
-
5
- // Utils
6
- export { createCache } from './utils/cache'
7
- export { shortAddress } from './utils/addresses'
8
- export { resolveChain } from './utils/chains'
9
- export { formatETH } from './utils/format-eth'
10
- export {
11
- ensCache,
12
- fetchEnsFromIndexer,
13
- fetchEnsFromChain,
14
- ENS_KEYS_AVATAR,
15
- ENS_KEYS_PROFILE,
16
- } from './utils/ens'
17
- export type { EnsProfile } from './utils/ens'
18
- export { stringifyJSON, parseJSON, formatPrice } from './utils/price'
19
- export { resolveUri } from './utils/uri'
20
- export type { ResolveUriOptions } from './utils/uri'
21
- export { createSiweMessage } from './utils/siwe'
22
- export type { SiweMessageParams } from './utils/siwe'
23
-
24
- // Composables
25
- export { useBaseURL } from './composables/base'
26
- export {
27
- useChainConfig,
28
- useMainChainId,
29
- useBlockExplorer,
30
- useEnsureChainIdCheck,
31
- } from './composables/chainId'
32
- export { useEns, useEnsWithAvatar, useEnsProfile } from './composables/ens'
33
- export { useResolveUri } from './composables/uri'
34
- export { useGasPrice } from './composables/gasPrice'
35
- export { usePriceFeed } from './composables/priceFeed'
36
- export { useWalletExplorer } from './composables/walletExplorer'
37
- export type { ExplorerWallet } from './composables/walletExplorer'
38
- export { useSiwe } from './composables/siwe'
39
- export type { SiweSession, UseSiweOptions } from './composables/siwe'
40
-
41
- // Connectors
42
- export { inAppWallet, prepareInAppWallet } from './connectors/inAppWallet'
43
-
44
- // Components
45
- export { default as EvmAccount } from './components/EvmAccount.vue'
46
- export { default as EvmAvatar } from './components/EvmAvatar.vue'
47
- export { default as EvmConnect } from './components/EvmConnect.vue'
48
- export { default as EvmConnectDialog } from './components/EvmConnectDialog.vue'
49
- export { default as EvmConnectionStatus } from './components/EvmConnectionStatus.vue'
50
- export { default as EvmProfile } from './components/EvmProfile.vue'
51
- export { default as EvmSwitchNetwork } from './components/EvmSwitchNetwork.vue'
52
- export { default as EvmConnectorQR } from './components/EvmConnectorQR.vue'
53
- export { default as EvmMetaMaskQR } from './components/EvmMetaMaskQR.vue'
54
- export { default as EvmWalletConnectQR } from './components/EvmWalletConnectQR.vue'
55
- export { default as EvmWalletConnectWallets } from './components/EvmWalletConnectWallets.vue'
56
- export { default as EvmTransactionFlow } from './components/EvmTransactionFlow.vue'
57
- export { default as EvmSeedPhraseInput } from './components/EvmSeedPhraseInput.vue'
58
- export { default as EvmInAppWalletSetup } from './components/EvmInAppWalletSetup.vue'
59
- export { default as EvmSiwe } from './components/EvmSiwe.vue'
60
- export { default as EvmSiweDialog } from './components/EvmSiweDialog.vue'
@@ -1,6 +0,0 @@
1
- import type { Address } from 'viem'
2
-
3
- export const shortAddress = (address: Address, length: number = 3) =>
4
- address.substring(0, length + 2) +
5
- '...' +
6
- address.substring(address.length - length)
@@ -1,59 +0,0 @@
1
- interface CacheEntry<T> {
2
- data: T
3
- expiresAt: number
4
- }
5
-
6
- export function createCache<T>(ttl: number, max: number) {
7
- const entries = new Map<string, CacheEntry<T>>()
8
- const pending = new Map<string, Promise<T>>()
9
-
10
- function prune() {
11
- const now = Date.now()
12
- for (const [key, entry] of entries) {
13
- if (entry.expiresAt <= now) entries.delete(key)
14
- }
15
-
16
- if (entries.size > max) {
17
- const excess = entries.size - max
18
- const keys = entries.keys()
19
- for (let i = 0; i < excess; i++) {
20
- entries.delete(keys.next().value!)
21
- }
22
- }
23
- }
24
-
25
- function get(key: string): T | undefined {
26
- const entry = entries.get(key)
27
- if (!entry) return undefined
28
- if (entry.expiresAt <= Date.now()) {
29
- entries.delete(key)
30
- return undefined
31
- }
32
- return entry.data
33
- }
34
-
35
- function fetch(key: string, fn: () => Promise<T>): Promise<T> {
36
- const cached = get(key)
37
- if (cached) return Promise.resolve(cached)
38
-
39
- const inflight = pending.get(key)
40
- if (inflight) return inflight
41
-
42
- const promise = fn()
43
- .then((result) => {
44
- entries.set(key, { data: result, expiresAt: Date.now() + ttl })
45
- pending.delete(key)
46
- if (entries.size > max) prune()
47
- return result
48
- })
49
- .catch((err) => {
50
- pending.delete(key)
51
- throw err
52
- })
53
-
54
- pending.set(key, promise)
55
- return promise
56
- }
57
-
58
- return { get, fetch }
59
- }
@@ -1,32 +0,0 @@
1
- import { defineChain, type Chain } from 'viem'
2
- import {
3
- mainnet,
4
- sepolia,
5
- holesky,
6
- optimism,
7
- arbitrum,
8
- base,
9
- polygon,
10
- localhost,
11
- } from 'viem/chains'
12
-
13
- const KNOWN: Chain[] = [
14
- mainnet,
15
- sepolia,
16
- holesky,
17
- optimism,
18
- arbitrum,
19
- base,
20
- polygon,
21
- localhost,
22
- ]
23
- const byId = new Map<number, Chain>(KNOWN.map((c) => [c.id, c]))
24
-
25
- export const resolveChain = (id: number): Chain =>
26
- byId.get(id) ??
27
- defineChain({
28
- id,
29
- name: `Chain ${id}`,
30
- nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
31
- rpcUrls: { default: { http: [] } },
32
- })