@lukso/transaction-view-core 0.4.1 → 0.5.0-dev.5916302
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 +20 -20
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +15 -0
- package/dist/index.cjs +131 -220
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -10
- package/dist/index.d.ts +1 -10
- package/dist/index.js +158 -252
- package/dist/index.js.map +1 -1
- package/dist/shared/index.cjs +31 -64
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +8 -20
- package/dist/shared/index.d.ts +8 -20
- package/dist/shared/index.js +43 -76
- package/dist/shared/index.js.map +1 -1
- package/dist/styles/index.cjs +1 -1
- package/dist/styles/index.cjs.map +1 -1
- package/dist/styles/index.js +1 -1
- package/dist/styles/index.js.map +1 -1
- package/package.json +5 -4
- package/src/components/asset-card.ts +63 -80
- package/src/components/contract-card.ts +2 -67
- package/src/components/info-panel.ts +1 -21
- package/src/components/permissions-block.ts +7 -5
- package/src/components/transaction-playback.ts +4 -4
- package/src/index.ts +1 -1
- package/src/shared/address-display.ts +3 -6
- package/src/shared/address-view.ts +2 -18
- package/src/shared/custom-select.ts +1 -1
- package/src/shared/function-name-view.ts +1 -1
- package/src/shared/gas-provider-view.ts +4 -7
- package/src/shared/icon-view.ts +7 -9
- package/src/shared/image-list.ts +3 -4
- package/src/shared/load-web-components.ts +3 -2
- package/src/shared/notification-view.ts +3 -3
- package/src/shared/progress-view.ts +1 -10
- package/src/shared/scroll-to-bottom-button.ts +1 -1
- package/src/shared/signal-controller.ts +3 -1
- package/src/shared/transaction-view-controller.ts +1 -1
- package/src/shared/url-view.ts +3 -3
- package/src/shared/value-view.ts +10 -30
- package/src/styles/styles.css +1 -1
- package/src/utils.test.ts +47 -0
- package/src/utils.ts +82 -0
- package/src/vue-entry.ts +0 -1
- package/tsup.config.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukso/transaction-view-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-dev.5916302",
|
|
4
4
|
"description": "Core components and hooks for LUKSO transaction display",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"@preact/signals-core": "^1.12.1",
|
|
36
36
|
"ethereum-blockies-base64": "^1.0.2",
|
|
37
37
|
"lit": "^3.3.1",
|
|
38
|
-
"@lukso/transaction-decoder": "1.
|
|
39
|
-
"@lukso/transaction-view-headless": "0.
|
|
38
|
+
"@lukso/transaction-decoder": "1.3.0-dev.5916302",
|
|
39
|
+
"@lukso/transaction-view-headless": "0.4.0-dev.5916302"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@tailwindcss/typography": "^0.5.19",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"build": "tsup",
|
|
53
53
|
"dev": "tsup --watch",
|
|
54
54
|
"dev-alt": "tsup --watch",
|
|
55
|
-
"clean": "rm -rf dist"
|
|
55
|
+
"clean": "rm -rf dist",
|
|
56
|
+
"typecheck": "tsc --noEmit"
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -11,26 +11,12 @@ import '../shared/image-list.js'
|
|
|
11
11
|
import '@lukso/web-components'
|
|
12
12
|
import { Task } from '@lit/task'
|
|
13
13
|
import {
|
|
14
|
-
ResolvedAddress,
|
|
14
|
+
type ResolvedAddress,
|
|
15
15
|
useAddressResolver,
|
|
16
16
|
} from '@lukso/transaction-view-headless'
|
|
17
17
|
import { safeCustomElement } from '../shared/safe-custom-element.js'
|
|
18
18
|
import { CoreLitElement } from '../styles'
|
|
19
|
-
|
|
20
|
-
// Value formatting utilities
|
|
21
|
-
function formatUnits(value: bigint, decimals = 18): string {
|
|
22
|
-
const divisor = 10n ** BigInt(decimals)
|
|
23
|
-
const quotient = value / divisor
|
|
24
|
-
const remainder = value % divisor
|
|
25
|
-
|
|
26
|
-
if (remainder === 0n) {
|
|
27
|
-
return quotient.toString()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const remainderStr = remainder.toString().padStart(decimals, '0')
|
|
31
|
-
const trimmed = remainderStr.replace(/0+$/, '')
|
|
32
|
-
return `${quotient}.${trimmed}`
|
|
33
|
-
}
|
|
19
|
+
import { formatUnits, parseBigInt } from '../utils.js'
|
|
34
20
|
|
|
35
21
|
/**
|
|
36
22
|
* Asset card component for displaying token/NFT information
|
|
@@ -58,9 +44,6 @@ export class AssetCard extends CoreLitElement {
|
|
|
58
44
|
@property({ type: String, attribute: 'function-icon' })
|
|
59
45
|
functionIcon: string = 'code-outline'
|
|
60
46
|
|
|
61
|
-
@property({ type: String })
|
|
62
|
-
size: 'small' | 'medium' | 'large' = 'medium'
|
|
63
|
-
|
|
64
47
|
@property({ type: Boolean, attribute: 'show-info-button' })
|
|
65
48
|
showInfoButton = true
|
|
66
49
|
|
|
@@ -73,13 +56,6 @@ export class AssetCard extends CoreLitElement {
|
|
|
73
56
|
@state()
|
|
74
57
|
private _resolvedData?: ResolvedAddress
|
|
75
58
|
|
|
76
|
-
@state()
|
|
77
|
-
private _imageError = false
|
|
78
|
-
|
|
79
|
-
private _handleImageError() {
|
|
80
|
-
this._imageError = true
|
|
81
|
-
}
|
|
82
|
-
|
|
83
59
|
private _handleInfoClick() {
|
|
84
60
|
this.displayDetails = !this.displayDetails
|
|
85
61
|
}
|
|
@@ -103,19 +79,6 @@ export class AssetCard extends CoreLitElement {
|
|
|
103
79
|
return addressOrComposite.split('-')[0]
|
|
104
80
|
}
|
|
105
81
|
|
|
106
|
-
private _extractTokenId(addressOrComposite: string): string | undefined {
|
|
107
|
-
const parts = addressOrComposite.split('-')
|
|
108
|
-
return parts.length > 1 ? parts[1] : undefined
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
private _copyToClipboard(text: string) {
|
|
112
|
-
if (navigator.clipboard) {
|
|
113
|
-
navigator.clipboard.writeText(text)
|
|
114
|
-
// Could dispatch a 'copied' event here for toast notifications
|
|
115
|
-
this.dispatchEvent(new CustomEvent('copied', { detail: { text } }))
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
82
|
private _renderAddressSection() {
|
|
120
83
|
const data = this._resolutionTask.value
|
|
121
84
|
if (!data) return ''
|
|
@@ -231,9 +194,7 @@ export class AssetCard extends CoreLitElement {
|
|
|
231
194
|
const displayTokenId = formattedTokenId ? `${formattedTokenId}` : ''
|
|
232
195
|
if (displayTokenId) return displayTokenId
|
|
233
196
|
// If its a collection, do not show tokenId
|
|
234
|
-
return this.tokenId
|
|
235
|
-
? `${parseInt(this.tokenId, 16)}`
|
|
236
|
-
: undefined
|
|
197
|
+
return this.tokenId ? `${parseInt(this.tokenId, 16)}` : undefined
|
|
237
198
|
}
|
|
238
199
|
|
|
239
200
|
private _renderTokenId() {
|
|
@@ -298,6 +259,7 @@ export class AssetCard extends CoreLitElement {
|
|
|
298
259
|
private _renderImages() {
|
|
299
260
|
const images = (this._resolvedData as any)?.images || []
|
|
300
261
|
if (images.length === 0) return ''
|
|
262
|
+
if (!this.address) return ''
|
|
301
263
|
|
|
302
264
|
return html`
|
|
303
265
|
<image-list
|
|
@@ -312,6 +274,7 @@ export class AssetCard extends CoreLitElement {
|
|
|
312
274
|
private _renderAssets() {
|
|
313
275
|
const assets = (this._resolvedData as any)?.assets || []
|
|
314
276
|
if (assets.length === 0) return ''
|
|
277
|
+
if (!this.address) return ''
|
|
315
278
|
|
|
316
279
|
return html`
|
|
317
280
|
<div class="section">
|
|
@@ -329,11 +292,11 @@ export class AssetCard extends CoreLitElement {
|
|
|
329
292
|
return html`
|
|
330
293
|
<div class="flex justify-between items-center my-4">
|
|
331
294
|
<function-name-view
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
295
|
+
label=${this.functionName || 'Execute'}
|
|
296
|
+
size="small"
|
|
297
|
+
icon=${this.functionIcon ? this.functionIcon : 'code-outline'}
|
|
335
298
|
></function-name-view>
|
|
336
|
-
<function-name-view label=${this._resolvedData?.standard} size="small"></function-name-view>
|
|
299
|
+
<function-name-view label=${this._resolvedData?.standard ?? 'Unknown'} size="small"></function-name-view>
|
|
337
300
|
</div>
|
|
338
301
|
`
|
|
339
302
|
}
|
|
@@ -354,6 +317,15 @@ export class AssetCard extends CoreLitElement {
|
|
|
354
317
|
`
|
|
355
318
|
}
|
|
356
319
|
|
|
320
|
+
private _formattedAmount() {
|
|
321
|
+
const data = this._resolutionTask.value
|
|
322
|
+
const amt = this.amount
|
|
323
|
+
if (amt === undefined || amt === null || amt === '') return undefined
|
|
324
|
+
const bigintAmount = parseBigInt(amt as any)
|
|
325
|
+
if (bigintAmount === undefined) return undefined
|
|
326
|
+
return formatUnits(bigintAmount, data?.decimals)
|
|
327
|
+
}
|
|
328
|
+
|
|
357
329
|
private renderFormattedTokenIdBadge() {
|
|
358
330
|
if (!this.displayedTokenId) return ''
|
|
359
331
|
return html`
|
|
@@ -365,54 +337,65 @@ export class AssetCard extends CoreLitElement {
|
|
|
365
337
|
return html`
|
|
366
338
|
<div >
|
|
367
339
|
${this._renderStandards()}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
340
|
+
<div class="mt-6 flex-col">
|
|
341
|
+
<div class="flex items-center justify-center gap-4">
|
|
342
|
+
<div class="flex justify-end w-[48%]">
|
|
343
|
+
<div class="border relative border-neutral-90 rounded-xl">
|
|
344
|
+
${this.renderFormattedTokenIdBadge()}
|
|
345
|
+
<div class="p-2 relative">
|
|
346
|
+
${when(
|
|
347
|
+
this.address,
|
|
348
|
+
() => html`
|
|
349
|
+
<icon-view
|
|
350
|
+
address=${this.address ?? ''}
|
|
351
|
+
size="2x-large"
|
|
352
|
+
.showName=${false}
|
|
353
|
+
></icon-view>
|
|
354
|
+
`
|
|
355
|
+
)}
|
|
356
|
+
</div>
|
|
357
|
+
<div style="height: 1px;" class="bg-neutral-90 w-full"></div>
|
|
358
|
+
<div class="px-2">
|
|
359
|
+
${this._renderAddressSection()}
|
|
360
|
+
</div>
|
|
383
361
|
</div>
|
|
384
362
|
</div>
|
|
385
|
-
</div>
|
|
386
363
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
364
|
+
<div class="flex flex-col gap-1 w-[51%]">
|
|
365
|
+
<div class="text-[14px] font-bold text-neutral-20">
|
|
366
|
+
${this._resolvedData?.lsp4TokenName || 'UNKNOWN'}
|
|
367
|
+
</div>
|
|
368
|
+
<div class="text-[17px] font-semibold text-neutral-20">
|
|
369
|
+
${when(
|
|
370
|
+
this.amount,
|
|
371
|
+
() => html`
|
|
372
|
+
<span class="">${this._formattedAmount() ?? ''}</span>
|
|
373
|
+
<span class="ml-1 text-neutral-60 max-w-[60px] whitespace-nowrap overflow-hidden text-ellipsis text-[14px] font-semibold">${
|
|
374
|
+
this._resolvedData?.lsp4TokenSymbol || ''
|
|
375
|
+
}</span>
|
|
376
|
+
`,
|
|
377
|
+
() => html`${this._resolvedData?.lsp4TokenSymbol || ''}`
|
|
378
|
+
)}
|
|
379
|
+
</div>
|
|
380
|
+
|
|
392
381
|
${when(
|
|
393
382
|
this.amount,
|
|
394
383
|
() => html`
|
|
395
|
-
<span class="">${formatUnits(BigInt(this.amount
|
|
384
|
+
<span class="">${formatUnits(BigInt(this.amount || 0), this._resolvedData?.decimals)}</span>
|
|
396
385
|
<span class="ml-1 text-neutral-60 max-w-[60px] whitespace-nowrap overflow-hidden text-ellipsis text-[14px] font-semibold">${
|
|
397
386
|
this._resolvedData?.lsp4TokenSymbol || ''
|
|
398
387
|
}</span>
|
|
399
388
|
`,
|
|
400
389
|
() => html`${this._resolvedData?.lsp4TokenSymbol || ''}`
|
|
401
390
|
)}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
this.displayedTokenId,
|
|
406
|
-
() =>
|
|
407
|
-
html`<div class="text-[14px] font-medium text-neutral-60"><span class="font-bold">#${this.displayedTokenId}</span></div>`
|
|
408
|
-
)}
|
|
409
|
-
<div class="mt-4">
|
|
410
|
-
${when(this.showCreator, () => this._renderCreatorSection())}
|
|
391
|
+
<div class="mt-4">
|
|
392
|
+
${when(this.showCreator, () => this._renderCreatorSection())}
|
|
393
|
+
</div>
|
|
411
394
|
</div>
|
|
412
395
|
</div>
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
396
|
+
<div class="border-neutral-90 pt-2">
|
|
397
|
+
${this._renderTokenDetails()}
|
|
398
|
+
</div>
|
|
416
399
|
</div>
|
|
417
400
|
</div>
|
|
418
401
|
`
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
type ResolvedAddress,
|
|
4
|
-
useAddressResolver,
|
|
5
|
-
useImageLoader,
|
|
6
|
-
} from '@lukso/transaction-view-headless'
|
|
7
|
-
import { css, html, LitElement, nothing } from 'lit'
|
|
1
|
+
import type { ResolvedAddress } from '@lukso/transaction-view-headless'
|
|
2
|
+
import { css, html, LitElement } from 'lit'
|
|
8
3
|
import { property, state } from 'lit/decorators.js'
|
|
9
4
|
import { safeCustomElement } from '../shared/safe-custom-element'
|
|
10
5
|
import '../shared/load-web-components'
|
|
@@ -115,66 +110,6 @@ export class ContractCard extends LitElement {
|
|
|
115
110
|
@state() private _profileImageUrl?: string
|
|
116
111
|
@state() private _backgroundImageUrl?: string
|
|
117
112
|
|
|
118
|
-
private _resolutionTask = new Task(this, {
|
|
119
|
-
task: async ([address, resolved]) => {
|
|
120
|
-
if (resolved) {
|
|
121
|
-
this._resolvedData = resolved
|
|
122
|
-
return resolved
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const { resolveAddress } = useAddressResolver()
|
|
126
|
-
const baseAddress = this._extractBaseAddress(address as string)
|
|
127
|
-
const data = await resolveAddress(baseAddress)
|
|
128
|
-
this._resolvedData = data
|
|
129
|
-
return data
|
|
130
|
-
},
|
|
131
|
-
args: () => [this.address, this.resolved] as const,
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
private _profileImageTask = new Task(this, {
|
|
135
|
-
task: async ([resolved]) => {
|
|
136
|
-
const { loadProfileImage } = useImageLoader()
|
|
137
|
-
const data = resolved || this._resolvedData
|
|
138
|
-
|
|
139
|
-
if (!data) return null
|
|
140
|
-
|
|
141
|
-
const image = await loadProfileImage(data, {
|
|
142
|
-
width: 256,
|
|
143
|
-
height: 256,
|
|
144
|
-
dpr: window.devicePixelRatio || 1,
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
if (image?.src) {
|
|
148
|
-
this._profileImageUrl = image.src
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return image
|
|
152
|
-
},
|
|
153
|
-
args: () => [this._resolvedData] as const,
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
private _backgroundImageTask = new Task(this, {
|
|
157
|
-
task: async ([resolved]) => {
|
|
158
|
-
const { loadBackgroundImage } = useImageLoader()
|
|
159
|
-
const data = resolved || this._resolvedData
|
|
160
|
-
|
|
161
|
-
if (!data) return null
|
|
162
|
-
|
|
163
|
-
const image = await loadBackgroundImage(data, {
|
|
164
|
-
width: 800,
|
|
165
|
-
height: 200,
|
|
166
|
-
dpr: window.devicePixelRatio || 1,
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
if (image?.src) {
|
|
170
|
-
this._backgroundImageUrl = image.src
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return image
|
|
174
|
-
},
|
|
175
|
-
args: () => [this._resolvedData] as const,
|
|
176
|
-
})
|
|
177
|
-
|
|
178
113
|
private _extractBaseAddress(addressOrComposite: string): string {
|
|
179
114
|
return addressOrComposite.split('-')[0]
|
|
180
115
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
type ResolvedAddress,
|
|
4
|
-
useAddressResolver,
|
|
5
|
-
} from '@lukso/transaction-view-headless'
|
|
1
|
+
import type { ResolvedAddress } from '@lukso/transaction-view-headless'
|
|
6
2
|
import { css, html, LitElement } from 'lit'
|
|
7
3
|
import { property, state } from 'lit/decorators.js'
|
|
8
4
|
import { classMap } from 'lit/directives/class-map.js'
|
|
@@ -34,25 +30,9 @@ export class InfoPanel extends LitElement {
|
|
|
34
30
|
@property({ type: String })
|
|
35
31
|
type: 'transfer' | 'mint' | 'burn' | 'approve' = 'transfer'
|
|
36
32
|
|
|
37
|
-
@state()
|
|
38
|
-
private _isAnimating = false
|
|
39
|
-
|
|
40
33
|
@state()
|
|
41
34
|
private _resolvedData?: ResolvedAddress
|
|
42
35
|
|
|
43
|
-
private _resolutionTask = new Task(this, {
|
|
44
|
-
task: async ([address]) => {
|
|
45
|
-
if (!address) return null
|
|
46
|
-
|
|
47
|
-
const { resolveAddress } = useAddressResolver()
|
|
48
|
-
// Resolve the full address (including tokenId if present) to get token-specific data
|
|
49
|
-
const data = await resolveAddress(address as string)
|
|
50
|
-
this._resolvedData = data
|
|
51
|
-
return data
|
|
52
|
-
},
|
|
53
|
-
args: () => [this.address] as const,
|
|
54
|
-
})
|
|
55
|
-
|
|
56
36
|
private _extractBaseAddress(addressOrComposite: string): string {
|
|
57
37
|
return addressOrComposite.split('-')[0]
|
|
58
38
|
}
|
|
@@ -79,13 +79,15 @@ export class PermissionsBlock extends CoreLitElement {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
private renderPermission(p: PermissionLevels) {
|
|
82
|
-
const nameBase = (p.icon || p.permissionName || '')
|
|
82
|
+
const nameBase = (p.icon || p.permissionName || '')
|
|
83
|
+
.toLowerCase()
|
|
84
|
+
.replace(/_/g, '-')
|
|
83
85
|
const activeIcon = `${nameBase}-activated`
|
|
84
86
|
const inactiveIcon = `${nameBase}-inactive`
|
|
85
87
|
return html`
|
|
86
88
|
<div class="mt-4 grid grid-cols-[40px,1fr,20px] gap-x-2 items-start">
|
|
87
89
|
<div class="relative w-10 h-10">
|
|
88
|
-
<
|
|
90
|
+
<lukso-icon
|
|
89
91
|
class="active absolute bottom-0 opacity-0 z-[99] transition-opacity duration-200 ${
|
|
90
92
|
p.isActive ? 'opacity-100' : ''
|
|
91
93
|
}"
|
|
@@ -93,14 +95,14 @@ export class PermissionsBlock extends CoreLitElement {
|
|
|
93
95
|
width="40"
|
|
94
96
|
height="40"
|
|
95
97
|
color=${this.color}
|
|
96
|
-
></
|
|
97
|
-
<
|
|
98
|
+
></lukso-icon>
|
|
99
|
+
<lukso-icon
|
|
98
100
|
class="inactive absolute bottom-0 ${p.isActive ? 'opacity-0' : 'opacity-100'}"
|
|
99
101
|
name=${inactiveIcon}
|
|
100
102
|
width="40"
|
|
101
103
|
height="40"
|
|
102
104
|
color=${this.color}
|
|
103
|
-
></
|
|
105
|
+
></lukso-icon>
|
|
104
106
|
</div>
|
|
105
107
|
|
|
106
108
|
<div>
|
|
@@ -231,7 +231,7 @@ export class TransactionPlayback extends LitElement {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
protected updated(
|
|
234
|
+
protected updated(_changedProperties: PropertyValues): void {
|
|
235
235
|
// Mount component after render
|
|
236
236
|
if (this.loadedComponent && this.componentContainerRef.value) {
|
|
237
237
|
// Clear existing content
|
|
@@ -364,14 +364,14 @@ export class TransactionPlayback extends LitElement {
|
|
|
364
364
|
() => html`
|
|
365
365
|
<div class="debug-item">
|
|
366
366
|
<span class="debug-label">Child Index:</span>
|
|
367
|
-
<span class="debug-value">${this.currentResult
|
|
367
|
+
<span class="debug-value">${this.currentResult?.indexInfo.childIndex}</span>
|
|
368
368
|
</div>
|
|
369
369
|
`
|
|
370
370
|
)}
|
|
371
371
|
<div class="debug-item">
|
|
372
372
|
<span class="debug-label">Available Indices:</span>
|
|
373
373
|
<span class="debug-value">
|
|
374
|
-
[${this.playbackState
|
|
374
|
+
[${this.playbackState?.batchInfo.availableIndices.join(', ')}]
|
|
375
375
|
</span>
|
|
376
376
|
</div>
|
|
377
377
|
${when(
|
|
@@ -379,7 +379,7 @@ export class TransactionPlayback extends LitElement {
|
|
|
379
379
|
() => html`
|
|
380
380
|
<div class="debug-item">
|
|
381
381
|
<span class="debug-label">Matched View:</span>
|
|
382
|
-
<span class="debug-value">${this.currentResult
|
|
382
|
+
<span class="debug-value">${this.currentResult?.match?.view.id}</span>
|
|
383
383
|
</div>
|
|
384
384
|
`
|
|
385
385
|
)}
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
useImageLoader,
|
|
5
5
|
} from '@lukso/transaction-view-headless'
|
|
6
6
|
import { css, html, LitElement } from 'lit'
|
|
7
|
-
import {
|
|
7
|
+
import { property } from 'lit/decorators.js'
|
|
8
8
|
import { safeCustomElement } from './safe-custom-element'
|
|
9
9
|
|
|
10
10
|
// LUKSO web components are loaded dynamically via plugin
|
|
@@ -96,17 +96,14 @@ export class AddressDisplay extends LitElement {
|
|
|
96
96
|
return this.value || this.address || ''
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
// Internal state
|
|
100
|
-
@state() private imageData?: { src: string }
|
|
101
|
-
@state() private isLoadingImage = false
|
|
102
|
-
|
|
103
99
|
// Composables
|
|
104
100
|
private imageLoader = useImageLoader()
|
|
105
101
|
private addressResolver = useAddressResolver()
|
|
102
|
+
isLoadingImage = false
|
|
106
103
|
|
|
107
104
|
// Task for loading profile image
|
|
108
105
|
private imageTask = new Task(this, {
|
|
109
|
-
task: async ([resolved]
|
|
106
|
+
task: async ([resolved]) => {
|
|
110
107
|
if (!resolved) return null
|
|
111
108
|
|
|
112
109
|
this.isLoadingImage = true
|
|
@@ -90,7 +90,7 @@ export class AddressView extends CoreLitElement {
|
|
|
90
90
|
|
|
91
91
|
// Task for resolving address data
|
|
92
92
|
private addressTask = new Task(this, {
|
|
93
|
-
task: async ([address]
|
|
93
|
+
task: async ([address]) => {
|
|
94
94
|
if (!address) return null
|
|
95
95
|
|
|
96
96
|
this.isLoadingAddress = true
|
|
@@ -99,7 +99,7 @@ export class AddressView extends CoreLitElement {
|
|
|
99
99
|
const resolved = await this.addressResolver.resolveAddress(address)
|
|
100
100
|
this.requestUpdate() // Force re-render after resolution
|
|
101
101
|
return resolved
|
|
102
|
-
} catch (
|
|
102
|
+
} catch (_error) {
|
|
103
103
|
return null
|
|
104
104
|
} finally {
|
|
105
105
|
this.isLoadingAddress = false
|
|
@@ -129,22 +129,6 @@ export class AddressView extends CoreLitElement {
|
|
|
129
129
|
return this.label || computedName || 'Anonymous'
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
/**
|
|
133
|
-
* Check if this is a contract address (non-profile)
|
|
134
|
-
*/
|
|
135
|
-
private get isContract(): boolean {
|
|
136
|
-
const resolved = this.addressTask.value
|
|
137
|
-
return resolved ? resolved.__gqltype !== 'Profile' : false
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Check if this should show the address hash (profiles show hash, contracts don't)
|
|
142
|
-
*/
|
|
143
|
-
private get shouldShowAddressHash(): boolean {
|
|
144
|
-
const resolved = this.addressTask.value
|
|
145
|
-
return resolved ? resolved.__gqltype === 'Profile' : true // Default to true for fallback
|
|
146
|
-
}
|
|
147
|
-
|
|
148
132
|
/**
|
|
149
133
|
* Get prefix for the address display
|
|
150
134
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit'
|
|
2
|
-
import {
|
|
2
|
+
import { property } from 'lit/decorators.js'
|
|
3
3
|
import { safeCustomElement } from './safe-custom-element'
|
|
4
4
|
import './load-web-components'
|
|
5
5
|
import makeBlockie from 'ethereum-blockies-base64'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit'
|
|
2
|
-
import {
|
|
2
|
+
import { property } from 'lit/decorators.js'
|
|
3
3
|
import { safeCustomElement } from './safe-custom-element'
|
|
4
4
|
import './load-web-components'
|
|
5
5
|
import { CoreLitElement } from '../styles'
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { Task } from '@lit/task'
|
|
2
|
-
import { useAddressResolver } from '@lukso/transaction-view-headless'
|
|
3
|
-
import makeBlockie from 'ethereum-blockies-base64'
|
|
4
1
|
import { html } from 'lit'
|
|
5
|
-
import {
|
|
2
|
+
import { property } from 'lit/decorators.js'
|
|
6
3
|
import { safeCustomElement } from './safe-custom-element'
|
|
7
4
|
import './load-web-components'
|
|
8
5
|
import { CoreLitElement } from '../styles'
|
|
@@ -148,7 +145,7 @@ export class GasProviderView extends CoreLitElement {
|
|
|
148
145
|
|
|
149
146
|
private displayRelayerResetDate() {
|
|
150
147
|
const date = new Date(this.relayerResetDate)
|
|
151
|
-
return isNaN(date.getTime()) ? 'N/A' : date.toLocaleDateString()
|
|
148
|
+
return Number.isNaN(date.getTime()) ? 'N/A' : date.toLocaleDateString()
|
|
152
149
|
}
|
|
153
150
|
|
|
154
151
|
override render() {
|
|
@@ -178,12 +175,12 @@ export class GasProviderView extends CoreLitElement {
|
|
|
178
175
|
? this.controllerAddress
|
|
179
176
|
: (() => {
|
|
180
177
|
const r = this.allRelayers.find(
|
|
181
|
-
(x) => x.id === this.selectedGasProvider
|
|
178
|
+
(x) => x.id === this.selectedGasProvider?.id
|
|
182
179
|
)
|
|
183
180
|
return (
|
|
184
181
|
r?.website ||
|
|
185
182
|
r?.apiUrl ||
|
|
186
|
-
`relayer:${this.selectedGasProvider
|
|
183
|
+
`relayer:${this.selectedGasProvider?.id}`
|
|
187
184
|
)
|
|
188
185
|
})()
|
|
189
186
|
: undefined
|
package/src/shared/icon-view.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Task } from '@lit/task'
|
|
2
2
|
import {
|
|
3
|
+
type ImageResult,
|
|
3
4
|
useAddressResolver,
|
|
4
5
|
useImageLoader,
|
|
5
6
|
} from '@lukso/transaction-view-headless'
|
|
6
7
|
import { html } from 'lit'
|
|
7
|
-
import {
|
|
8
|
+
import { property } from 'lit/decorators.js'
|
|
8
9
|
import { CoreLitElement } from '../styles'
|
|
9
10
|
import { safeCustomElement } from './safe-custom-element'
|
|
10
11
|
|
|
@@ -115,18 +116,15 @@ export class IconView extends CoreLitElement {
|
|
|
115
116
|
*/
|
|
116
117
|
@property({ type: Number, attribute: 'image-index' }) imageIndex?: number
|
|
117
118
|
|
|
118
|
-
// Internal state
|
|
119
|
-
@state() private imageData?: { src: string }
|
|
120
|
-
@state() private isLoadingImage = false
|
|
121
|
-
@state() private isLoadingAddress = false
|
|
122
|
-
|
|
123
119
|
// Composables
|
|
124
120
|
private imageLoader = useImageLoader()
|
|
125
121
|
private addressResolver = useAddressResolver()
|
|
122
|
+
isLoadingAddress = false
|
|
123
|
+
isLoadingImage = false
|
|
126
124
|
|
|
127
125
|
// Task for resolving address data
|
|
128
126
|
private addressTask = new Task(this, {
|
|
129
|
-
task: async ([address]
|
|
127
|
+
task: async ([address]) => {
|
|
130
128
|
if (!address) return null
|
|
131
129
|
|
|
132
130
|
this.isLoadingAddress = true
|
|
@@ -147,12 +145,12 @@ export class IconView extends CoreLitElement {
|
|
|
147
145
|
|
|
148
146
|
// Task for loading profile image
|
|
149
147
|
private imageTask = new Task(this, {
|
|
150
|
-
task: async ([resolved]
|
|
148
|
+
task: async ([resolved]) => {
|
|
151
149
|
if (!resolved) return null
|
|
152
150
|
|
|
153
151
|
this.isLoadingImage = true
|
|
154
152
|
try {
|
|
155
|
-
let image
|
|
153
|
+
let image: ImageResult | null = null
|
|
156
154
|
|
|
157
155
|
// If imageHint is specified, load directly from that property
|
|
158
156
|
if (this.imageHint && (resolved as any)[this.imageHint]) {
|
package/src/shared/image-list.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Task } from '@lit/task'
|
|
2
2
|
import { useAddressResolver } from '@lukso/transaction-view-headless'
|
|
3
3
|
import { html } from 'lit'
|
|
4
|
-
import {
|
|
4
|
+
import { property, state } from 'lit/decorators.js'
|
|
5
5
|
import { repeat } from 'lit/directives/repeat.js'
|
|
6
6
|
import { safeCustomElement } from './safe-custom-element'
|
|
7
7
|
import './icon-view.js'
|
|
@@ -72,7 +72,7 @@ export class ImageList extends CoreLitElement {
|
|
|
72
72
|
|
|
73
73
|
// Task for resolving address data
|
|
74
74
|
private addressTask = new Task(this, {
|
|
75
|
-
task: async ([address]
|
|
75
|
+
task: async ([address]) => {
|
|
76
76
|
if (!address) return null
|
|
77
77
|
|
|
78
78
|
this.isLoading = true
|
|
@@ -140,7 +140,7 @@ export class ImageList extends CoreLitElement {
|
|
|
140
140
|
* Render a single image item
|
|
141
141
|
*/
|
|
142
142
|
private renderImageItem(item: any, index: number) {
|
|
143
|
-
const
|
|
143
|
+
const _itemIndex = item.index !== undefined ? item.index : index
|
|
144
144
|
const isImage = this.isImageFile(item)
|
|
145
145
|
|
|
146
146
|
if (isImage) {
|
|
@@ -237,7 +237,6 @@ export class ImageList extends CoreLitElement {
|
|
|
237
237
|
</div>
|
|
238
238
|
`
|
|
239
239
|
}
|
|
240
|
-
|
|
241
240
|
const grid = html`
|
|
242
241
|
<div class="grid grid-cols-[repeat(auto-fill,minmax(${this.getImageMinSizePx()}px,300px))] gap-3 p-2">
|
|
243
242
|
${repeat(
|
|
@@ -34,11 +34,12 @@ const originalDefine =
|
|
|
34
34
|
|
|
35
35
|
// Wrap customElements.define to catch duplicate registration errors
|
|
36
36
|
if (typeof customElements !== 'undefined' && originalDefine) {
|
|
37
|
-
customElements.define =
|
|
37
|
+
customElements.define = (
|
|
38
38
|
name: string,
|
|
39
|
+
// biome-ignore lint/suspicious/noShadowRestrictedNames: This is the web-components api.
|
|
39
40
|
constructor: CustomElementConstructor,
|
|
40
41
|
options?: ElementDefinitionOptions
|
|
41
|
-
) {
|
|
42
|
+
) => {
|
|
42
43
|
// Check if already defined
|
|
43
44
|
if (!customElements.get(name)) {
|
|
44
45
|
originalDefine(name, constructor, options)
|