@lukso/transaction-view-core 0.5.0-dev.f500300 → 0.5.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.
- package/.turbo/turbo-build.log +19 -19
- package/dist/index.cjs +220 -131
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +252 -158
- package/dist/index.js.map +1 -1
- package/dist/shared/index.cjs +64 -31
- package/dist/shared/index.cjs.map +1 -1
- package/dist/shared/index.d.cts +20 -8
- package/dist/shared/index.d.ts +20 -8
- package/dist/shared/index.js +76 -43
- 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 +4 -5
- package/src/components/asset-card.ts +80 -63
- package/src/components/contract-card.ts +67 -2
- package/src/components/info-panel.ts +21 -1
- package/src/components/permissions-block.ts +5 -7
- package/src/components/transaction-playback.ts +4 -4
- package/src/shared/address-display.ts +6 -3
- package/src/shared/address-view.ts +18 -2
- package/src/shared/custom-select.ts +1 -1
- package/src/shared/function-name-view.ts +1 -1
- package/src/shared/gas-provider-view.ts +7 -4
- package/src/shared/icon-view.ts +9 -7
- package/src/shared/image-list.ts +4 -3
- package/src/shared/load-web-components.ts +2 -3
- package/src/shared/notification-view.ts +3 -3
- package/src/shared/progress-view.ts +10 -1
- package/src/shared/scroll-to-bottom-button.ts +1 -1
- package/src/shared/signal-controller.ts +1 -3
- package/src/shared/transaction-view-controller.ts +1 -1
- package/src/shared/url-view.ts +3 -3
- package/src/shared/value-view.ts +30 -10
- package/src/styles/styles.css +1 -1
- package/src/vue-entry.ts +1 -0
- package/tsup.config.ts +3 -3
- package/.turbo/turbo-typecheck.log +0 -4
- package/src/utils.test.ts +0 -47
- package/src/utils.ts +0 -82
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit'
|
|
2
|
-
import { property, state } from 'lit/decorators.js'
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
3
3
|
import { safeCustomElement } from './safe-custom-element'
|
|
4
4
|
import './load-web-components'
|
|
5
5
|
import { CoreLitElement } from '../styles'
|
|
@@ -58,7 +58,7 @@ export class NotificationView extends CoreLitElement {
|
|
|
58
58
|
return html`
|
|
59
59
|
<div class="grid grid-cols-[24px_1fr] items-start gap-3 p-3 rounded-xl text-neutral-10 leading-snug ${this.getVariantBackgroundClass()}">
|
|
60
60
|
<div class="flex items-center justify-center text-[16px] text-neutral-20 self-center" aria-hidden="true">
|
|
61
|
-
<lukso-icon name="${this.renderIcon()}" size="
|
|
61
|
+
<lukso-icon name="${this.renderIcon()}" size="large" color="${this.getVariantColor()}"></lukso-icon>
|
|
62
62
|
</div>
|
|
63
63
|
<div class="text-[14px] flex flex-col gap-1.5">
|
|
64
64
|
${
|
|
@@ -66,7 +66,7 @@ export class NotificationView extends CoreLitElement {
|
|
|
66
66
|
? html`<div class="font-semibold text-neutral-20 paragraph-inter-14-semi-bold">${this.title}</div>`
|
|
67
67
|
: ''
|
|
68
68
|
}
|
|
69
|
-
<div class="text-neutral-
|
|
69
|
+
<div class="text-neutral-30"><slot>${this.message}</slot></div>
|
|
70
70
|
${
|
|
71
71
|
this.acknowledgeable
|
|
72
72
|
? html`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit'
|
|
2
|
-
import { property } from 'lit/decorators.js'
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
3
3
|
import { CoreLitElement } from '../styles'
|
|
4
4
|
import { safeCustomElement } from './safe-custom-element'
|
|
5
5
|
|
|
@@ -42,6 +42,15 @@ export class ProgressView extends CoreLitElement {
|
|
|
42
42
|
`
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
private renderAddressLabel() {
|
|
46
|
+
return html`
|
|
47
|
+
<value-view
|
|
48
|
+
.value=${this.address}
|
|
49
|
+
.unit=${this.unit}
|
|
50
|
+
></value-view>
|
|
51
|
+
`
|
|
52
|
+
}
|
|
53
|
+
|
|
45
54
|
override render() {
|
|
46
55
|
const isError = (this.className || '').split(/\s+/).includes('error')
|
|
47
56
|
return html`
|
|
@@ -90,9 +90,7 @@ export class MultiSignalController implements ReactiveController {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
hostDisconnected() {
|
|
93
|
-
this.unsubscribes.forEach((unsubscribe) =>
|
|
94
|
-
unsubscribe()
|
|
95
|
-
})
|
|
93
|
+
this.unsubscribes.forEach((unsubscribe) => unsubscribe())
|
|
96
94
|
this.unsubscribes = []
|
|
97
95
|
}
|
|
98
96
|
|
|
@@ -255,7 +255,7 @@ export function useTransactionView(
|
|
|
255
255
|
/**
|
|
256
256
|
* Controller for working with transaction signals from the decoder
|
|
257
257
|
*/
|
|
258
|
-
export class TransactionSignalController<
|
|
258
|
+
export class TransactionSignalController<T = any>
|
|
259
259
|
implements ReactiveController
|
|
260
260
|
{
|
|
261
261
|
private host: ReactiveControllerHost
|
package/src/shared/url-view.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit'
|
|
2
|
-
import { property, state } from 'lit/decorators.js'
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
3
3
|
import { safeCustomElement } from './safe-custom-element'
|
|
4
4
|
import './load-web-components'
|
|
5
5
|
import { CoreLitElement } from '../styles'
|
|
@@ -56,7 +56,7 @@ export class UrlView extends CoreLitElement {
|
|
|
56
56
|
.replace(/-/g, ' ')
|
|
57
57
|
.replace(/\b\w/g, (c) => c.toUpperCase())
|
|
58
58
|
|
|
59
|
-
if (this.label
|
|
59
|
+
if (this.label && this.label.trim()) {
|
|
60
60
|
this.displayName = this.label.trim()
|
|
61
61
|
} else {
|
|
62
62
|
this.displayName = hostnamePretty || this.url
|
|
@@ -64,7 +64,7 @@ export class UrlView extends CoreLitElement {
|
|
|
64
64
|
} catch {
|
|
65
65
|
this.favicon = undefined
|
|
66
66
|
// Fallback to raw string if URL parse fails
|
|
67
|
-
this.displayName = this.label
|
|
67
|
+
this.displayName = this.label && this.label.trim() ? this.label : this.url
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
package/src/shared/value-view.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Task } from '@lit/task'
|
|
2
2
|
import { useAddressResolver } from '@lukso/transaction-view-headless'
|
|
3
|
-
import {
|
|
3
|
+
import { css, 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
|
-
|
|
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?:
|
|
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
|
|
101
|
+
@property() label?: string
|
|
88
102
|
|
|
89
103
|
/**
|
|
90
104
|
* Maximum width for truncation
|
|
@@ -97,6 +111,13 @@ export class ValueView extends CoreLitElement {
|
|
|
97
111
|
*/
|
|
98
112
|
@property() address?: string
|
|
99
113
|
|
|
114
|
+
// Internal state for resolved metadata
|
|
115
|
+
@state() private resolvedMetadata?: {
|
|
116
|
+
symbol?: string
|
|
117
|
+
decimals?: number
|
|
118
|
+
name?: string
|
|
119
|
+
}
|
|
120
|
+
|
|
100
121
|
// Tracks whether the component has any slotted content
|
|
101
122
|
@state() private _hasSlotContent = false
|
|
102
123
|
|
|
@@ -198,16 +219,15 @@ export class ValueView extends CoreLitElement {
|
|
|
198
219
|
if (value === undefined) return 'undefined'
|
|
199
220
|
|
|
200
221
|
switch (effectiveType) {
|
|
201
|
-
case 'currency':
|
|
222
|
+
case 'currency':
|
|
202
223
|
const { numeric, symbol } = this.getCurrencyParts()
|
|
203
224
|
return `${numeric} ${symbol}`
|
|
204
|
-
}
|
|
205
225
|
|
|
206
226
|
case 'bigint':
|
|
207
227
|
if (typeof value === 'bigint') {
|
|
208
|
-
return
|
|
228
|
+
return value.toString() + 'n'
|
|
209
229
|
}
|
|
210
|
-
return
|
|
230
|
+
return String(value) + 'n'
|
|
211
231
|
|
|
212
232
|
case 'boolean':
|
|
213
233
|
return value ? 'true' : 'false'
|
|
@@ -250,7 +270,7 @@ export class ValueView extends CoreLitElement {
|
|
|
250
270
|
try {
|
|
251
271
|
if (typeof value === 'bigint') {
|
|
252
272
|
numeric = formatUnits(value, effectiveDecimals)
|
|
253
|
-
} else if (typeof value === 'string' && !
|
|
273
|
+
} else if (typeof value === 'string' && !isNaN(Number(value))) {
|
|
254
274
|
const bigintValue = BigInt(value)
|
|
255
275
|
numeric = formatUnits(bigintValue, effectiveDecimals)
|
|
256
276
|
}
|
|
@@ -366,7 +386,7 @@ export class ValueView extends CoreLitElement {
|
|
|
366
386
|
|
|
367
387
|
if (effectiveType === 'currency') {
|
|
368
388
|
const { numeric, symbol } = this.getCurrencyParts()
|
|
369
|
-
if (this.label) {
|
|
389
|
+
if (this.label && this.label.trim() !== '') {
|
|
370
390
|
headerText = this.label
|
|
371
391
|
contentTemplate = html`
|
|
372
392
|
<span class="inline-block overflow-hidden text-ellipsis whitespace-nowrap min-w-0 ${this.getNumericClass()}">${numeric}</span>
|
package/src/styles/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import "@lukso/web-components/
|
|
1
|
+
@import "@lukso/web-components/dist/styles/main.css";
|
package/src/vue-entry.ts
CHANGED
package/tsup.config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs'
|
|
2
|
-
import { dirname, resolve } from 'node:path'
|
|
3
1
|
import autoprefixer from 'autoprefixer'
|
|
2
|
+
import { readFileSync } from 'fs'
|
|
3
|
+
import { dirname, resolve } from 'path'
|
|
4
4
|
import postcss from 'postcss'
|
|
5
5
|
import postcssImport from 'postcss-import'
|
|
6
6
|
import tailwindcss from 'tailwindcss'
|
|
@@ -37,7 +37,7 @@ export default defineConfig({
|
|
|
37
37
|
// Return with a special virtual path marker that the onLoad hook can recognize
|
|
38
38
|
// Use 'file' namespace to ensure esbuild calls our onLoad handler
|
|
39
39
|
return {
|
|
40
|
-
path:
|
|
40
|
+
path: resolvedPath + '?__raw__',
|
|
41
41
|
namespace: 'file',
|
|
42
42
|
}
|
|
43
43
|
})
|
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
|
-
}
|