@lukso/transaction-view-headless 0.2.2-dev.a8c9315
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/.turbo/turbo-build.log +51 -0
- package/CHANGELOG.md +88 -0
- package/COMPONENT_ARCHITECTURE.md +190 -0
- package/COMPONENT_CONVERSION_ANALYSIS.md +371 -0
- package/CONTEXT_VARIANT_GUIDE.md +425 -0
- package/LAZY_LOADING_GUIDE.md +534 -0
- package/LICENSE +201 -0
- package/PLAYBACK_EXAMPLES.md +658 -0
- package/PLAYBACK_GUIDE.md +402 -0
- package/README.md +43 -0
- package/REGISTRY_SUMMARY.md +638 -0
- package/SUFFERING_ECONOMICS.md +346 -0
- package/SUFFERING_ECONOMICS.zip +0 -0
- package/VIEW_REGISTRATION_GUIDE.md +795 -0
- package/dist/composables/index.cjs +1321 -0
- package/dist/composables/index.cjs.map +1 -0
- package/dist/composables/index.d.cts +6 -0
- package/dist/composables/index.d.ts +6 -0
- package/dist/composables/index.js +1276 -0
- package/dist/composables/index.js.map +1 -0
- package/dist/index-CMLU1hKL.d.ts +374 -0
- package/dist/index-CSDjhiKV.d.cts +374 -0
- package/dist/index.cjs +1534 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +93 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +1463 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/index.cjs +522 -0
- package/dist/registry/index.cjs.map +1 -0
- package/dist/registry/index.d.cts +46 -0
- package/dist/registry/index.d.ts +46 -0
- package/dist/registry/index.js +487 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/types/index.cjs +19 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +203 -0
- package/dist/types/index.d.ts +203 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.cjs +217 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +47 -0
- package/dist/utils/index.d.ts +47 -0
- package/dist/utils/index.js +188 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/view-loader-dD86QAlQ.d.cts +121 -0
- package/dist/view-loader-ii8AxiQR.d.ts +121 -0
- package/package.json +64 -0
- package/publish.log +0 -0
- package/src/composables/index.ts +59 -0
- package/src/composables/use-image-loader.ts +315 -0
- package/src/composables/use-transaction-playback.ts +396 -0
- package/src/composables/use-transaction-view.ts +309 -0
- package/src/config/lukso-config.ts +171 -0
- package/src/examples/context-aware-views.ts +300 -0
- package/src/examples/example-views.ts +197 -0
- package/src/examples/lit-plus-rn-strategy.ts +448 -0
- package/src/examples/lsp7-custom-matcher-examples.ts +174 -0
- package/src/examples/opt-in-context-examples.ts +372 -0
- package/src/examples/optimized-view-definitions.ts +408 -0
- package/src/examples/vue-to-lit-compilation.ts +358 -0
- package/src/hooks/useAddressQuery.ts +135 -0
- package/src/hooks/useAddressResolution.ts +437 -0
- package/src/index.ts +36 -0
- package/src/registry/index.ts +13 -0
- package/src/registry/view-loader.ts +305 -0
- package/src/registry/view-registry.ts +135 -0
- package/src/types/index.ts +16 -0
- package/src/types/view-contexts.ts +72 -0
- package/src/types/view-matching.ts +173 -0
- package/src/utils/context-matcher.ts +165 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/view-matcher.ts +338 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +34 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic address resolution hook
|
|
3
|
+
* Can be adapted for Vue (composable), React (hook), or Lit (controller)
|
|
4
|
+
* Uses batching mechanism inspired by the decoder package
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
AssetData,
|
|
9
|
+
EnhancedInfo,
|
|
10
|
+
ImageData,
|
|
11
|
+
LinkData,
|
|
12
|
+
ProfileData,
|
|
13
|
+
TokenData,
|
|
14
|
+
} from '@lukso/transaction-decoder'
|
|
15
|
+
import type { Chain } from 'viem'
|
|
16
|
+
import {
|
|
17
|
+
cacheAddress,
|
|
18
|
+
currentChainSignal,
|
|
19
|
+
getCachedAddress,
|
|
20
|
+
getLuksoConfig,
|
|
21
|
+
initializeChainSignal,
|
|
22
|
+
isAddressResolutionEnabled,
|
|
23
|
+
} from '../config/lukso-config'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Union type of all possible resolved address data
|
|
27
|
+
* Combines Profile, Asset, and Token data structures
|
|
28
|
+
*/
|
|
29
|
+
export type ResolvedAddress = {
|
|
30
|
+
address: string
|
|
31
|
+
hasProfile: boolean
|
|
32
|
+
truncatedAddress: string
|
|
33
|
+
__gqltype?: 'Profile' | 'Asset' | 'Token' | 'Contract'
|
|
34
|
+
} & Partial<ProfileData> &
|
|
35
|
+
Partial<AssetData> &
|
|
36
|
+
Partial<TokenData>
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Truncate address to 0x{first5}...{last4} format
|
|
40
|
+
*/
|
|
41
|
+
function truncateAddress(
|
|
42
|
+
address: string,
|
|
43
|
+
prefixLength = 5,
|
|
44
|
+
suffixLength = 4
|
|
45
|
+
): string {
|
|
46
|
+
if (!address || address.length <= prefixLength + suffixLength + 2) {
|
|
47
|
+
return address
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const prefix = address.slice(0, 2 + prefixLength) // 0x + first 5
|
|
51
|
+
const suffix = address.slice(-suffixLength) // last 4
|
|
52
|
+
|
|
53
|
+
return `${prefix}...${suffix}`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Per-chain batching state
|
|
57
|
+
interface ChainBatchState {
|
|
58
|
+
batchTimeout: NodeJS.Timeout | null
|
|
59
|
+
batchQueue: Set<string>
|
|
60
|
+
batchResolvers: Map<string, (result: ResolvedAddress) => void>
|
|
61
|
+
pendingResolutions: Map<string, Promise<ResolvedAddress>>
|
|
62
|
+
isProcessing: boolean // Prevent concurrent batch processing
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const chainBatchStates = new Map<number, ChainBatchState>()
|
|
66
|
+
const BATCH_DELAY = 0 // Just wait for next tick to batch addresses from the same render cycle
|
|
67
|
+
const BATCH_SIZE = 50
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get or create batch state for a specific chain
|
|
71
|
+
*/
|
|
72
|
+
function getBatchState(chainId: number): ChainBatchState {
|
|
73
|
+
let state = chainBatchStates.get(chainId)
|
|
74
|
+
if (!state) {
|
|
75
|
+
state = {
|
|
76
|
+
batchTimeout: null,
|
|
77
|
+
batchQueue: new Set<string>(),
|
|
78
|
+
batchResolvers: new Map<string, (result: ResolvedAddress) => void>(),
|
|
79
|
+
pendingResolutions: new Map<string, Promise<ResolvedAddress>>(),
|
|
80
|
+
isProcessing: false,
|
|
81
|
+
}
|
|
82
|
+
chainBatchStates.set(chainId, state)
|
|
83
|
+
}
|
|
84
|
+
return state
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Process a batch of addresses using decoder package's GraphQL resolver
|
|
89
|
+
*/
|
|
90
|
+
async function processBatch(chainId: number): Promise<void> {
|
|
91
|
+
const state = getBatchState(chainId)
|
|
92
|
+
if (state.batchQueue.size === 0 || state.isProcessing) return
|
|
93
|
+
|
|
94
|
+
// Prevent concurrent processing for this chain
|
|
95
|
+
state.isProcessing = true
|
|
96
|
+
|
|
97
|
+
const addresses = Array.from(state.batchQueue)
|
|
98
|
+
state.batchQueue.clear()
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
// Use decoder package's GraphQL resolver
|
|
102
|
+
// @ts-ignore - Declaration files may not be ready during development
|
|
103
|
+
const { fetchMultipleAddresses, getGraphQLEndpoint } = await import(
|
|
104
|
+
'@lukso/transaction-decoder'
|
|
105
|
+
)
|
|
106
|
+
const { lukso, luksoTestnet } = await import('viem/chains')
|
|
107
|
+
|
|
108
|
+
// Get the appropriate chain
|
|
109
|
+
const chain = chainId === 42 ? lukso : luksoTestnet
|
|
110
|
+
const graphqlEndpoint = getGraphQLEndpoint(chain)
|
|
111
|
+
|
|
112
|
+
// Convert addresses to DataKey format expected by decoder
|
|
113
|
+
const dataKeys = addresses as any[] // DataKey is a hex string type
|
|
114
|
+
|
|
115
|
+
// Fetch using decoder package
|
|
116
|
+
const results = await fetchMultipleAddresses(dataKeys, graphqlEndpoint)
|
|
117
|
+
|
|
118
|
+
// Process results and resolve promises
|
|
119
|
+
for (const address of addresses) {
|
|
120
|
+
const normalizedAddress = address.toLowerCase() as any
|
|
121
|
+
const enhanced: EnhancedInfo | undefined = results.get(normalizedAddress)
|
|
122
|
+
|
|
123
|
+
let result: ResolvedAddress
|
|
124
|
+
|
|
125
|
+
if (enhanced) {
|
|
126
|
+
// Just pass through the enhanced data as-is - no need to restructure
|
|
127
|
+
const profileImages = (enhanced as Record<string, any>).profileImages
|
|
128
|
+
const resolvedData = {
|
|
129
|
+
...enhanced,
|
|
130
|
+
hasProfile: !!(enhanced.name || profileImages?.length),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Cache the result with chainId
|
|
134
|
+
cacheAddressForChain(address, resolvedData, chainId)
|
|
135
|
+
|
|
136
|
+
result = {
|
|
137
|
+
...resolvedData,
|
|
138
|
+
address,
|
|
139
|
+
truncatedAddress: truncateAddress(address),
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
// No profile found
|
|
143
|
+
result = {
|
|
144
|
+
address,
|
|
145
|
+
truncatedAddress: truncateAddress(address),
|
|
146
|
+
hasProfile: false,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Cache negative result with chainId
|
|
150
|
+
cacheAddressForChain(address, { hasProfile: false }, chainId)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Resolve the promise
|
|
154
|
+
const resolver = state.batchResolvers.get(normalizedAddress)
|
|
155
|
+
if (resolver) {
|
|
156
|
+
resolver(result)
|
|
157
|
+
state.batchResolvers.delete(normalizedAddress)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.warn(
|
|
162
|
+
'Batch address resolution failed (falling back to API):',
|
|
163
|
+
error
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
// Fallback to original API approach if decoder package fails
|
|
167
|
+
try {
|
|
168
|
+
const response = await fetch('/api/resolveAddresses', {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
headers: { 'Content-Type': 'application/json' },
|
|
171
|
+
body: JSON.stringify({
|
|
172
|
+
addresses,
|
|
173
|
+
chainId: chainId,
|
|
174
|
+
}),
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
throw new Error(`API fallback failed: ${response.status}`)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const data = await response.json()
|
|
182
|
+
|
|
183
|
+
// Process API results
|
|
184
|
+
for (const address of addresses) {
|
|
185
|
+
const normalizedAddress = address.toLowerCase()
|
|
186
|
+
const resolved = data.resolved?.[normalizedAddress]
|
|
187
|
+
|
|
188
|
+
let result: ResolvedAddress
|
|
189
|
+
|
|
190
|
+
if (resolved) {
|
|
191
|
+
const resolvedData = {
|
|
192
|
+
name: resolved.name,
|
|
193
|
+
profileImage: resolved.profileImage,
|
|
194
|
+
hasProfile: !!(resolved.name || resolved.profileImage),
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
cacheAddressForChain(address, resolvedData, chainId)
|
|
198
|
+
|
|
199
|
+
result = {
|
|
200
|
+
address,
|
|
201
|
+
truncatedAddress: truncateAddress(address),
|
|
202
|
+
...resolvedData,
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
result = {
|
|
206
|
+
address,
|
|
207
|
+
truncatedAddress: truncateAddress(address),
|
|
208
|
+
hasProfile: false,
|
|
209
|
+
}
|
|
210
|
+
cacheAddressForChain(address, { hasProfile: false }, chainId)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const resolver = state.batchResolvers.get(normalizedAddress)
|
|
214
|
+
if (resolver) {
|
|
215
|
+
resolver(result)
|
|
216
|
+
state.batchResolvers.delete(normalizedAddress)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
} catch (fallbackError) {
|
|
220
|
+
console.warn('Both GraphQL and API resolution failed:', fallbackError)
|
|
221
|
+
|
|
222
|
+
// Return fallbacks for all addresses
|
|
223
|
+
for (const address of addresses) {
|
|
224
|
+
const fallback: ResolvedAddress = {
|
|
225
|
+
address,
|
|
226
|
+
truncatedAddress: truncateAddress(address),
|
|
227
|
+
hasProfile: false,
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
cacheAddressForChain(address, { hasProfile: false }, chainId)
|
|
231
|
+
|
|
232
|
+
const resolver = state.batchResolvers.get(address.toLowerCase())
|
|
233
|
+
if (resolver) {
|
|
234
|
+
resolver(fallback)
|
|
235
|
+
state.batchResolvers.delete(address.toLowerCase())
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
} finally {
|
|
240
|
+
// Always reset processing flag
|
|
241
|
+
state.isProcessing = false
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Chain-aware address cache functions
|
|
247
|
+
*/
|
|
248
|
+
function cacheAddressForChain(
|
|
249
|
+
address: string,
|
|
250
|
+
data: any,
|
|
251
|
+
chainId: number
|
|
252
|
+
): void {
|
|
253
|
+
const key = `${address.toLowerCase()}:${chainId}`
|
|
254
|
+
cacheAddress(key, data)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function getCachedAddressForChain(
|
|
258
|
+
address: string,
|
|
259
|
+
chainId: number
|
|
260
|
+
): any | null {
|
|
261
|
+
const key = `${address.toLowerCase()}:${chainId}`
|
|
262
|
+
return getCachedAddress(key)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Get effective chain ID from parameter or current signal
|
|
267
|
+
*/
|
|
268
|
+
async function getEffectiveChainId(chainId?: number): Promise<number> {
|
|
269
|
+
if (chainId !== undefined) return chainId
|
|
270
|
+
|
|
271
|
+
// Initialize chain signal if needed
|
|
272
|
+
await initializeChainSignal()
|
|
273
|
+
|
|
274
|
+
// Get from signal or fall back to global config
|
|
275
|
+
const currentChain = currentChainSignal.value
|
|
276
|
+
if (currentChain) {
|
|
277
|
+
return currentChain.id
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Final fallback to global config
|
|
281
|
+
const config = getLuksoConfig()
|
|
282
|
+
return config.chainId
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Resolve a single address using batched resolution
|
|
287
|
+
* Returns immediately with cached data or fallback, then updates with resolved data
|
|
288
|
+
* Handles both plain addresses and address-tokenId composite format (with - separator)
|
|
289
|
+
*/
|
|
290
|
+
export async function resolveAddress(
|
|
291
|
+
address: string,
|
|
292
|
+
chainId?: number
|
|
293
|
+
): Promise<ResolvedAddress> {
|
|
294
|
+
const effectiveChainId = await getEffectiveChainId(chainId)
|
|
295
|
+
const normalizedAddress = address.toLowerCase()
|
|
296
|
+
|
|
297
|
+
// Always provide truncated fallback using the original address
|
|
298
|
+
const fallback: ResolvedAddress = {
|
|
299
|
+
address,
|
|
300
|
+
truncatedAddress: truncateAddress(address),
|
|
301
|
+
hasProfile: false,
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Return fallback immediately if resolution disabled
|
|
305
|
+
if (!isAddressResolutionEnabled()) {
|
|
306
|
+
return fallback
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Check cache first (chain-aware)
|
|
310
|
+
const cached = getCachedAddressForChain(address, effectiveChainId)
|
|
311
|
+
if (cached) {
|
|
312
|
+
return {
|
|
313
|
+
...fallback,
|
|
314
|
+
...cached,
|
|
315
|
+
hasProfile: !!(cached.name || cached.profileImage),
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const state = getBatchState(effectiveChainId)
|
|
320
|
+
|
|
321
|
+
// Check if resolution is already pending for this chain
|
|
322
|
+
const existingPromise = state.pendingResolutions.get(normalizedAddress)
|
|
323
|
+
if (existingPromise) {
|
|
324
|
+
return existingPromise
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Safety check: if we already have this address in the batch queue, return a fast fallback
|
|
328
|
+
if (state.batchQueue.has(normalizedAddress)) {
|
|
329
|
+
return Promise.resolve(fallback)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Create new resolution promise
|
|
333
|
+
const resolutionPromise = new Promise<ResolvedAddress>((resolve) => {
|
|
334
|
+
// Add full address to batch queue (supports address-tokenId format with -)
|
|
335
|
+
state.batchQueue.add(normalizedAddress)
|
|
336
|
+
state.batchResolvers.set(normalizedAddress, resolve)
|
|
337
|
+
|
|
338
|
+
// Clear existing timeout
|
|
339
|
+
if (state.batchTimeout) {
|
|
340
|
+
clearTimeout(state.batchTimeout)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Set new timeout for batch processing (only if not already processing)
|
|
344
|
+
if (!state.isProcessing) {
|
|
345
|
+
state.batchTimeout = setTimeout(() => {
|
|
346
|
+
state.batchTimeout = null
|
|
347
|
+
processBatch(effectiveChainId)
|
|
348
|
+
}, BATCH_DELAY)
|
|
349
|
+
|
|
350
|
+
// Process immediately if batch is full
|
|
351
|
+
if (state.batchQueue.size >= BATCH_SIZE) {
|
|
352
|
+
if (state.batchTimeout) {
|
|
353
|
+
clearTimeout(state.batchTimeout)
|
|
354
|
+
state.batchTimeout = null
|
|
355
|
+
}
|
|
356
|
+
processBatch(effectiveChainId)
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
// Store the promise to avoid duplicate requests
|
|
362
|
+
state.pendingResolutions.set(normalizedAddress, resolutionPromise)
|
|
363
|
+
|
|
364
|
+
// Clean up after resolution
|
|
365
|
+
resolutionPromise.finally(() => {
|
|
366
|
+
state.pendingResolutions.delete(normalizedAddress)
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
return resolutionPromise
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Resolve multiple addresses
|
|
374
|
+
*/
|
|
375
|
+
export async function resolveAddresses(
|
|
376
|
+
addresses: string[],
|
|
377
|
+
chainId?: number
|
|
378
|
+
): Promise<Map<string, ResolvedAddress>> {
|
|
379
|
+
const results = new Map<string, ResolvedAddress>()
|
|
380
|
+
|
|
381
|
+
// Resolve all addresses in parallel using the batched resolver
|
|
382
|
+
const resolutionPromises = addresses.map(async (address) => {
|
|
383
|
+
const resolved = await resolveAddress(address, chainId)
|
|
384
|
+
results.set(address.toLowerCase(), resolved)
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
await Promise.all(resolutionPromises)
|
|
388
|
+
return results
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Simple reactive state for frameworks to implement
|
|
393
|
+
* Each framework will wrap this with their reactivity system
|
|
394
|
+
*/
|
|
395
|
+
export interface AddressResolutionState {
|
|
396
|
+
resolved: ResolvedAddress | null
|
|
397
|
+
loading: boolean
|
|
398
|
+
error: string | null
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Create initial state
|
|
403
|
+
*/
|
|
404
|
+
export function createAddressResolutionState(): AddressResolutionState {
|
|
405
|
+
return {
|
|
406
|
+
resolved: null,
|
|
407
|
+
loading: false,
|
|
408
|
+
error: null,
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Framework-agnostic resolution function that updates state
|
|
414
|
+
*/
|
|
415
|
+
export async function resolveAddressWithState(
|
|
416
|
+
address: string,
|
|
417
|
+
_state: AddressResolutionState,
|
|
418
|
+
updateCallback: (newState: Partial<AddressResolutionState>) => void,
|
|
419
|
+
chainId?: number
|
|
420
|
+
): Promise<void> {
|
|
421
|
+
// Start loading
|
|
422
|
+
updateCallback({ loading: true, error: null })
|
|
423
|
+
|
|
424
|
+
try {
|
|
425
|
+
const resolved = await resolveAddress(address, chainId)
|
|
426
|
+
updateCallback({
|
|
427
|
+
resolved,
|
|
428
|
+
loading: false,
|
|
429
|
+
error: null,
|
|
430
|
+
})
|
|
431
|
+
} catch (error) {
|
|
432
|
+
updateCallback({
|
|
433
|
+
loading: false,
|
|
434
|
+
error: error instanceof Error ? error.message : 'Resolution failed',
|
|
435
|
+
})
|
|
436
|
+
}
|
|
437
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Main exports for the decoder-headless package
|
|
2
|
+
|
|
3
|
+
export type {
|
|
4
|
+
AddressImageData,
|
|
5
|
+
AddressResolutionState,
|
|
6
|
+
ImageLoadOptions,
|
|
7
|
+
ImageResult,
|
|
8
|
+
LuksoConfig,
|
|
9
|
+
ResolvedAddress,
|
|
10
|
+
UseTransactionViewOptions,
|
|
11
|
+
UseTransactionViewResult,
|
|
12
|
+
} from './composables'
|
|
13
|
+
export * from './composables'
|
|
14
|
+
export {
|
|
15
|
+
findBestTransactionView,
|
|
16
|
+
useTransactionView,
|
|
17
|
+
} from './composables'
|
|
18
|
+
// Configuration and address resolution (framework-agnostic)
|
|
19
|
+
export * from './config/lukso-config'
|
|
20
|
+
export * from './hooks/useAddressQuery'
|
|
21
|
+
export * from './hooks/useAddressResolution'
|
|
22
|
+
export * from './registry'
|
|
23
|
+
// Convenience re-exports for common use cases
|
|
24
|
+
export {
|
|
25
|
+
getGlobalLoader,
|
|
26
|
+
getGlobalRegistry,
|
|
27
|
+
} from './registry'
|
|
28
|
+
export type {
|
|
29
|
+
DecoderRecordForSelection,
|
|
30
|
+
ViewContext,
|
|
31
|
+
ViewDefinition,
|
|
32
|
+
ViewMatch,
|
|
33
|
+
ViewMatchCriteria,
|
|
34
|
+
} from './types'
|
|
35
|
+
export * from './types'
|
|
36
|
+
export * from './utils'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export {
|
|
2
|
+
getGlobalLoader,
|
|
3
|
+
LoaderHelpers,
|
|
4
|
+
setGlobalLoader,
|
|
5
|
+
UniversalViewLoader,
|
|
6
|
+
ViewLoadingError,
|
|
7
|
+
} from './view-loader'
|
|
8
|
+
export {
|
|
9
|
+
DefaultViewRegistry,
|
|
10
|
+
getGlobalRegistry,
|
|
11
|
+
resetGlobalRegistry,
|
|
12
|
+
setGlobalRegistry,
|
|
13
|
+
} from './view-registry'
|