@lukso/transaction-view-core 0.5.0-dev.5916302 → 0.5.0-dev.a98e9bc

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukso/transaction-view-core",
3
- "version": "0.5.0-dev.5916302",
3
+ "version": "0.5.0-dev.a98e9bc",
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.3.0-dev.5916302",
39
- "@lukso/transaction-view-headless": "0.4.0-dev.5916302"
38
+ "@lukso/transaction-decoder": "1.3.0-dev.a98e9bc",
39
+ "@lukso/transaction-view-headless": "0.4.0-dev.a98e9bc"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@tailwindcss/typography": "^0.5.19",
@@ -16,7 +16,21 @@ import {
16
16
  } from '@lukso/transaction-view-headless'
17
17
  import { safeCustomElement } from '../shared/safe-custom-element.js'
18
18
  import { CoreLitElement } from '../styles'
19
- import { formatUnits, parseBigInt } from '../utils.js'
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
+ }
20
34
 
21
35
  /**
22
36
  * Asset card component for displaying token/NFT information
@@ -44,6 +58,9 @@ export class AssetCard extends CoreLitElement {
44
58
  @property({ type: String, attribute: 'function-icon' })
45
59
  functionIcon: string = 'code-outline'
46
60
 
61
+ @property({ type: String })
62
+ size: 'small' | 'medium' | 'large' = 'medium'
63
+
47
64
  @property({ type: Boolean, attribute: 'show-info-button' })
48
65
  showInfoButton = true
49
66
 
@@ -194,7 +211,9 @@ export class AssetCard extends CoreLitElement {
194
211
  const displayTokenId = formattedTokenId ? `${formattedTokenId}` : ''
195
212
  if (displayTokenId) return displayTokenId
196
213
  // If its a collection, do not show tokenId
197
- return this.tokenId ? `${parseInt(this.tokenId, 16)}` : undefined
214
+ return this.tokenId && !this._resolvedData?.isCollection
215
+ ? `${parseInt(this.tokenId, 16)}`
216
+ : undefined
198
217
  }
199
218
 
200
219
  private _renderTokenId() {
@@ -259,7 +278,6 @@ export class AssetCard extends CoreLitElement {
259
278
  private _renderImages() {
260
279
  const images = (this._resolvedData as any)?.images || []
261
280
  if (images.length === 0) return ''
262
- if (!this.address) return ''
263
281
 
264
282
  return html`
265
283
  <image-list
@@ -274,7 +292,6 @@ export class AssetCard extends CoreLitElement {
274
292
  private _renderAssets() {
275
293
  const assets = (this._resolvedData as any)?.assets || []
276
294
  if (assets.length === 0) return ''
277
- if (!this.address) return ''
278
295
 
279
296
  return html`
280
297
  <div class="section">
@@ -292,11 +309,11 @@ export class AssetCard extends CoreLitElement {
292
309
  return html`
293
310
  <div class="flex justify-between items-center my-4">
294
311
  <function-name-view
295
- label=${this.functionName || 'Execute'}
296
- size="small"
297
- icon=${this.functionIcon ? this.functionIcon : 'code-outline'}
312
+ label=${this.functionName}
313
+ size="small"
314
+ icon=${this.functionIcon ? this.functionIcon : 'code-outline'}
298
315
  ></function-name-view>
299
- <function-name-view label=${this._resolvedData?.standard ?? 'Unknown'} size="small"></function-name-view>
316
+ <function-name-view label=${this._resolvedData?.standard} size="small"></function-name-view>
300
317
  </div>
301
318
  `
302
319
  }
@@ -317,15 +334,6 @@ export class AssetCard extends CoreLitElement {
317
334
  `
318
335
  }
319
336
 
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
-
329
337
  private renderFormattedTokenIdBadge() {
330
338
  if (!this.displayedTokenId) return ''
331
339
  return html`
@@ -337,47 +345,30 @@ export class AssetCard extends CoreLitElement {
337
345
  return html`
338
346
  <div >
339
347
  ${this._renderStandards()}
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>
348
+ <div class="mt-6 flex-col">
349
+ <div class="flex items-center justify-center gap-4">
350
+ <div class="flex justify-end w-[48%]">
351
+ <div class="border relative border-neutral-90 rounded-xl">
352
+ ${this.renderFormattedTokenIdBadge()}
353
+ <div class="p-2 relative">
354
+ <icon-view
355
+ address="${this.address}"
356
+ size="2x-large"
357
+ .showName=${false}
358
+ ></icon-view>
359
+ </div>
360
+ <div style="height: 1px;" class="bg-neutral-90 w-full"></div>
361
+ <div class="px-2">
362
+ ${this._renderAddressSection()}
361
363
  </div>
362
364
  </div>
365
+ </div>
363
366
 
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
-
367
+ <div class="flex flex-col gap-1 w-[51%]">
368
+ <div class="text-[14px] font-bold text-neutral-20">
369
+ ${this._resolvedData?.lsp4TokenName || 'UNKNOWN'}
370
+ </div>
371
+ <div class="text-[17px] font-semibold text-neutral-20">
381
372
  ${when(
382
373
  this.amount,
383
374
  () => html`
@@ -388,14 +379,20 @@ export class AssetCard extends CoreLitElement {
388
379
  `,
389
380
  () => html`${this._resolvedData?.lsp4TokenSymbol || ''}`
390
381
  )}
391
- <div class="mt-4">
392
- ${when(this.showCreator, () => this._renderCreatorSection())}
393
- </div>
382
+ </div>
383
+
384
+ ${when(
385
+ this.displayedTokenId,
386
+ () =>
387
+ html`<div class="text-[14px] font-medium text-neutral-60"><span class="font-bold">#${this.displayedTokenId}</span></div>`
388
+ )}
389
+ <div class="mt-4">
390
+ ${when(this.showCreator, () => this._renderCreatorSection())}
394
391
  </div>
395
392
  </div>
396
- <div class="border-neutral-90 pt-2">
397
- ${this._renderTokenDetails()}
398
- </div>
393
+ </div>
394
+ <div class="border-neutral-90 pt-2">
395
+ ${this._renderTokenDetails()}
399
396
  </div>
400
397
  </div>
401
398
  `
@@ -237,6 +237,7 @@ export class ImageList extends CoreLitElement {
237
237
  </div>
238
238
  `
239
239
  }
240
+
240
241
  const grid = html`
241
242
  <div class="grid grid-cols-[repeat(auto-fill,minmax(${this.getImageMinSizePx()}px,300px))] gap-3 p-2">
242
243
  ${repeat(
@@ -1,6 +1,6 @@
1
1
  import { Task } from '@lit/task'
2
2
  import { useAddressResolver } from '@lukso/transaction-view-headless'
3
- import { html, type TemplateResult } from 'lit'
3
+ import { html } from 'lit'
4
4
  import { property, state } from 'lit/decorators.js'
5
5
  import { when } from 'lit/directives/when.js'
6
6
  import { safeCustomElement } from './safe-custom-element'
@@ -8,7 +8,21 @@ import { safeCustomElement } from './safe-custom-element'
8
8
  // Import LUKSO web components
9
9
  import './load-web-components'
10
10
  import { CoreLitElement } from '../styles'
11
- import { formatUnits } from '../utils'
11
+
12
+ // Value formatting utilities
13
+ function formatUnits(value: bigint, decimals = 18): string {
14
+ const divisor = 10n ** BigInt(decimals)
15
+ const quotient = value / divisor
16
+ const remainder = value % divisor
17
+
18
+ if (remainder === 0n) {
19
+ return quotient.toString()
20
+ }
21
+
22
+ const remainderStr = remainder.toString().padStart(decimals, '0')
23
+ const trimmed = remainderStr.replace(/0+$/, '')
24
+ return `${quotient}.${trimmed}`
25
+ }
12
26
 
13
27
  /**
14
28
  * Value display component
@@ -33,7 +47,7 @@ export class ValueView extends CoreLitElement {
33
47
  * The value to display (required)
34
48
  * Can be string, number, boolean, or bigint
35
49
  */
36
- @property() value?: TemplateResult | string | number | boolean | bigint | null
50
+ @property() value?: string | number | boolean | bigint | null
37
51
 
38
52
  /**
39
53
  * The key name (used for special formatting logic)
@@ -84,7 +98,7 @@ export class ValueView extends CoreLitElement {
84
98
  /**
85
99
  * Optional label to show in card header
86
100
  */
87
- @property() label?: string | TemplateResult
101
+ @property() label?: string
88
102
 
89
103
  /**
90
104
  * Maximum width for truncation
@@ -366,7 +380,7 @@ export class ValueView extends CoreLitElement {
366
380
 
367
381
  if (effectiveType === 'currency') {
368
382
  const { numeric, symbol } = this.getCurrencyParts()
369
- if (this.label) {
383
+ if (this.label && this.label.trim() !== '') {
370
384
  headerText = this.label
371
385
  contentTemplate = html`
372
386
  <span class="inline-block overflow-hidden text-ellipsis whitespace-nowrap min-w-0 ${this.getNumericClass()}">${numeric}</span>
package/src/utils.test.ts DELETED
@@ -1,47 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { formatUnits, parseBigInt } from './utils.js'
3
-
4
- describe('formatUnits', () => {
5
- it('returns integer string when remainder is zero', () => {
6
- expect(formatUnits(1000000000000000000n)).toBe('1')
7
- expect(formatUnits(5000n, 3)).toBe('5')
8
- })
9
-
10
- it('formats values with fractional part respecting decimals', () => {
11
- expect(formatUnits(123000000000000000n)).toBe('0.123')
12
- expect(formatUnits(987654321n, 6)).toBe('987.654321')
13
- })
14
-
15
- it('trims trailing zeros in fractional part', () => {
16
- expect(formatUnits(120n, 2)).toBe('1.2')
17
- expect(formatUnits(1001000n, 6)).toBe('1.001')
18
- })
19
-
20
- it('handles zero value', () => {
21
- expect(formatUnits(0n)).toBe('0')
22
- })
23
- })
24
-
25
- describe('parseBigInt', () => {
26
- it('parses decimal and hex strings with optional suffix', () => {
27
- expect(parseBigInt('42')).toBe(42n)
28
- expect(parseBigInt('0x10')).toBe(16n)
29
- expect(parseBigInt('21n')).toBe(21n)
30
- expect(parseBigInt(' 0xFFn ')).toBe(255n)
31
- })
32
-
33
- it('returns bigint directly or from integer numbers', () => {
34
- const value = 123n
35
- expect(parseBigInt(value)).toBe(value)
36
- expect(parseBigInt(9007199254740991)).toBe(9007199254740991n)
37
- })
38
-
39
- it('returns undefined for invalid inputs', () => {
40
- expect(parseBigInt('')).toBeUndefined()
41
- expect(parseBigInt('1.5')).toBeUndefined()
42
- expect(parseBigInt('0xG')).toBeUndefined()
43
- expect(parseBigInt(1.1)).toBeUndefined()
44
- expect(parseBigInt(null)).toBeUndefined()
45
- expect(parseBigInt(undefined)).toBeUndefined()
46
- })
47
- })
package/src/utils.ts DELETED
@@ -1,82 +0,0 @@
1
- // Value formatting utilities
2
- /**
3
- * Convert a token amount from base units (bigint) to a decimal string.
4
- *
5
- * - Handles arbitrary `decimals` without floating point precision loss.
6
- * - Trims trailing zeros in the fractional part.
7
- * - Returns only the integer part when remainder is zero.
8
- *
9
- * @param value - The amount in base units as a bigint (e.g., wei for ETH).
10
- * @param decimals - Number of decimal places the token uses (default 18).
11
- * @returns A human-readable decimal string.
12
- *
13
- * @example
14
- * // 1 ether in wei
15
- * formatUnits(1000000000000000000n) // '1'
16
- *
17
- * @example
18
- * // 1.23 tokens with 2 decimals
19
- * formatUnits(123n, 2) // '1.23'
20
- *
21
- * @example
22
- * // No remainder: return integer part only
23
- * formatUnits(2000000000000000000n) // '2'
24
- */
25
- export function formatUnits(value: bigint, decimals = 18): string {
26
- const divisor = 10n ** BigInt(decimals)
27
- const quotient = value / divisor
28
- const remainder = value % divisor
29
-
30
- if (remainder === 0n) {
31
- return quotient.toString()
32
- }
33
-
34
- const remainderStr = remainder.toString().padStart(decimals, '0')
35
- const trimmed = remainderStr.replace(/0+$/, '')
36
- return `${quotient}.${trimmed}`
37
- }
38
-
39
- function isBigIntString(str: string): boolean {
40
- const trimmed = str.trim()
41
- if (trimmed.endsWith('n'))
42
- return /^[0-9]+n$/.test(trimmed) || /^0x[0-9a-fA-F]+n$/.test(trimmed)
43
- return /^[0-9]+$/.test(trimmed) || /^0x[0-9a-fA-F]+$/.test(trimmed)
44
- }
45
-
46
- /**
47
- * Parse loose bigint inputs coming from attributes, JSON, or user input.
48
- *
49
- * - Accepts bigint literals (`123n`), decimal/hex strings, and integers.
50
- * - Trims whitespace and optional trailing `n` suffix.
51
- * - Returns `undefined` for invalid formats (floats, empty strings, non-numeric text).
52
- *
53
- * @param value - Source value to parse (string | number | bigint | null | undefined).
54
- * @returns BigInt when parsing succeeds, otherwise `undefined`.
55
- *
56
- * @example
57
- * parseBigInt('42') // 42n
58
- * @example
59
- * parseBigInt('0x10n') // 16n
60
- * @example
61
- * parseBigInt(1000n) // 1000n (passthrough)
62
- * @example
63
- * parseBigInt('1.5') // undefined (decimals not allowed)
64
- */
65
- export function parseBigInt(
66
- value: string | number | bigint | null | undefined
67
- ): bigint | undefined {
68
- if (!value) return undefined
69
- if (typeof value === 'bigint') return value
70
- if (typeof value === 'number') {
71
- if (!Number.isInteger(value)) return undefined
72
- return BigInt(value)
73
- }
74
- const trimmed = value.trim()
75
- const cleaned = trimmed.endsWith('n') ? trimmed.slice(0, -1) : trimmed
76
- if (!isBigIntString(cleaned)) return undefined
77
- try {
78
- return BigInt(cleaned)
79
- } catch {
80
- return undefined
81
- }
82
- }