šŸš€ Big News:Socket Has Acquired Secure Annex.Learn More →
Socket
Book a DemoSign in
Socket

@lukso/core

Package Overview
Dependencies
Maintainers
2
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lukso/core

Core utilities, services, and mixins for LUKSO web components and applications

latest
Source
npmnpm
Version
1.7.0
Version published
Weekly downloads
261
-26.06%
Maintainers
2
Weekly downloads
Ā 
Created
Source

@lukso/core

npm version

Core utilities, services, and mixins for LUKSO web components and applications.

Installation

pnpm add @lukso/core
# or
npm install @lukso/core
# or
yarn add @lukso/core

Peer Dependencies

This package requires lit as a peer dependency (for the Lit mixins):

pnpm add lit

If you're using chain definitions with viem types, you'll also need:

pnpm add viem

Features

Package contains some basic elements:

  • Services
  • Utility functions
  • Lit Mixins
  • Chain Definitions
  • Types
  • Configurations

Services

Device

Detect device type, OS, and browser:

import { deviceService } from '@lukso/core/services/device'

const device = deviceService()
if (device.isMobile) {
  console.log('Mobile device detected')
}

console.log({
  os: device.isMacOS ? 'macOS' : device.isWindows ? 'Windows' : 'Unknown',
  browser: device.isSafari ? 'Safari' : device.isChrome ? 'Chrome' : 'Unknown',
})

Intl

Format messages, numbers, and dates:

import { createIntlService, setIntlService } from '@lukso/core/services/intl'

const intl = createIntlService({
  locale: 'en-US',
  messages: {
    'app.welcome': 'Welcome',
    'app.hello': 'Hello, {name}!',
  },
})
setIntlService(intl)

console.log(intl.formatMessage('app.welcome')) // 'Welcome'
console.log(intl.formatMessage('app.hello', { name: 'John' })) // 'Hello, John!'
console.log(intl.formatNumber(1234.56)) // '1,234.56'

// Enable warnings for missing translations (useful for debugging)
const intlWithWarnings = createIntlService({
  locale: 'en-US',
  messages: {
    'app.welcome': 'Welcome',
  },
  onError: (err) => {
    console.error('Translation error:', err)
  },
})

Note: By default, missing translation warnings are suppressed since translations are optional. To enable warnings during development, pass a custom onError handler.

Utility functions

browserInfo

Detect browser type and get browser-specific metadata (name, icon, store link):

import { browserInfo, type BrowserInfo } from '@lukso/core/utils'
import { deviceService } from '@lukso/core/services'

const device = deviceService()
const browser: BrowserInfo = browserInfo(device)

console.log(browser.id) // 'chrome', 'firefox', 'safari', 'edge', 'brave', 'opera'
console.log(browser.name) // 'Chrome', 'Firefox', 'Safari', etc.
console.log(browser.icon) // 'logo-chrome', 'logo-firefox', etc.
console.log(browser.storeLink) // URL to browser's extension store for Universal Profile

The browserInfo function is useful for:

  • Showing browser-specific Universal Profile extension installation links
  • Displaying browser icons in UI
  • Determining browser-specific features or limitations
  • Customizing UX based on browser capabilities

isLyx

Check if an asset is the native LYX token:

import { isLyx } from '@lukso/core/utils'

isLyx({ isNativeToken: true }) // true
isLyx({ standard: 'LSP7DigitalAsset' }) // false

isToken

Check if an asset is a fungible token (including native LYX):

import { isToken } from '@lukso/core/utils'

isToken({ isNativeToken: true }) // true (LYX)
isToken({ standard: 'LSP7DigitalAsset', tokenType: 0 }) // true (Token)
isToken({ standard: 'LSP7DigitalAsset', tokenType: 1 }) // false (NFT)
isToken({ standard: 'LSP8IdentifiableDigitalAsset', tokenType: 0 }) // false

isCollectible

Check if an asset is a collectible (NFT or collection) based on its LSP standard and token type:

import { isCollectible } from '@lukso/core/utils'

isCollectible({ standard: 'LSP7DigitalAsset', tokenType: 1 }) // true (NFT)
isCollectible({ standard: 'LSP8IdentifiableDigitalAsset', tokenType: 2 }) // true (Collection)
isCollectible({ standard: 'LSP7DigitalAsset', tokenType: 0 }) // false (Token)

slug

Convert text to slug format (lowercase with hyphens):

import { slug } from '@lukso/core/utils'

console.log(slug('Hello World')) // 'hello-world'
console.log(slug('TEST')) // 'test'
console.log(slug('some-text')) // 'some-text'
console.log(slug('')) // ''

The slug function is useful for:

  • Creating URL-friendly identifiers
  • Generating CSS class names
  • Normalizing user input

Signed QR Codes (Check-in URLs)

Create and verify signed QR codes for Universal Profile check-ins. This is useful for proving ownership of a Universal Profile without on-chain transactions.

URI Format: ethereum:<address>@<chainId>?ts=<unixTimestamp>&sig=<signature>

import {
  createSignedQR,
  verifySignedQR,
  parseSignedQR,
  isSignedQRFormat,
  getControllerAddress,
  getEIP1271Data,
  EIP1271_MAGIC_VALUE,
} from '@lukso/core/utils'

Creating a signed QR code:

// Using a private key directly
const uri = await createSignedQR(
  '0x1234...', // controller private key
  '0xabcd...', // profile address
  42,          // LUKSO mainnet (or 4201 for testnet)
  { generationOffsetSeconds: 2 } // optional: account for QR display latency
)
// Returns: ethereum:0xabcd...@42?ts=1706345678&sig=0x...

// Using a custom signer (WalletConnect, hardware wallet, etc.)
const uri = await createSignedQR(
  null,        // not needed when signer is provided
  '0xabcd...', // profile address
  42,
  {
    signer: async (message) => await wallet.signMessage(message)
  }
)

Verifying a signed QR code:

const result = await verifySignedQR(uri, {
  maxAgeSeconds: 60, // default: 60 seconds
})

if (result.isValid) {
  console.log('Profile:', result.profileAddress)
  console.log('Chain ID:', result.chainId)
  console.log('Signed by:', result.recoveredAddress)
  console.log('Timestamp:', result.timestamp)
  console.log('Is expired:', result.isExpired)
}

EIP-1271 verification (for smart contract wallets):

import { createPublicClient, http } from 'viem'
import { lukso } from 'viem/chains'

const result = await verifySignedQR(uri)
const { hash, signature } = getEIP1271Data(uri, result)

// Call isValidSignature on the Universal Profile contract
const client = createPublicClient({ chain: lukso, transport: http() })
const magicValue = await client.readContract({
  address: result.profileAddress,
  abi: [{
    name: 'isValidSignature',
    type: 'function',
    stateMutability: 'view',
    inputs: [
      { name: 'dataHash', type: 'bytes32' },
      { name: 'signature', type: 'bytes' },
    ],
    outputs: [{ name: '', type: 'bytes4' }],
  }],
  functionName: 'isValidSignature',
  args: [hash, signature],
})

const isAuthorizedController = magicValue === EIP1271_MAGIC_VALUE

Quick format check:

if (isSignedQRFormat(uri)) {
  // Valid format, proceed with verification
  const parsed = parseSignedQR(uri)
  console.log(parsed?.profileAddress, parsed?.chainId)
}

Get controller address from private key:

const controllerAddress = getControllerAddress('0x1234...')
console.log('Will sign as:', controllerAddress)

The signed QR code functionality is useful for:

  • Event check-ins without on-chain transactions
  • Proving Universal Profile ownership
  • Time-limited access tokens
  • QR-based authentication flows

Lit Mixins

withDeviceService

Add device detection to your component:

import { LitElement, html } from 'lit'
import { customElement } from 'lit/decorators.js'
import { withDeviceService } from '@lukso/core/mixins'

@customElement('my-component')
export class MyComponent extends withDeviceService(LitElement) {
  render() {
    return html`
      <div>
        Is mobile: ${this.device?.isMobile}
        Is Safari: ${this.device?.isSafari}
      </div>
    `
  }
}

withIntlService

Add internationalization to your component:

import { LitElement, html } from 'lit'
import { customElement } from 'lit/decorators.js'
import { withIntlService } from '@lukso/core/mixins'

@customElement('my-component')
export class MyComponent extends withIntlService(LitElement) {
  render() {
    return html`
      <h1>${this.formatMessage('app.title')}</h1>
      <p>${this.formatMessage('app.welcome')}</p>
    `
  }
}

withTheme

Add theme management with automatic dark mode support:

import { LitElement, html } from 'lit'
import { customElement } from 'lit/decorators.js'
import { withTheme } from '@lukso/core/mixins'

@customElement('my-component')
export class MyComponent extends withTheme(LitElement) {
  render() {
    return html`
      <div class="bg-neutral-100 dark:bg-neutral-10">
        <h1 class="text-neutral-10 dark:text-neutral-100">
          Hello World
        </h1>
        <p>Current theme: ${this.theme}</p>
        <p>Is dark mode: ${this.isDark}</p>
      </div>
    `
  }
}

Features:

  • Manual theme selection: Set theme to 'light', 'dark', or 'auto'
  • System preference detection: Automatically follows OS dark mode when theme is 'auto'
  • Reactive updates: Listens for system theme changes and updates automatically
  • Automatic wrapping: All rendered content is wrapped in a div with data-theme-root attribute
  • Tailwind integration: The wrapper div receives the dark class for Tailwind's dark mode utilities

API:

  • theme ('light' | 'dark' | 'auto'): The theme mode (reflects to attribute)
  • isDark (boolean): Read-only computed state indicating if dark mode is active

HTML Structure:

<!-- Light mode -->
<my-component theme="light">
  #shadow-root
    <div data-theme-root>
      <!-- Your component's rendered content -->
    </div>
</my-component>

<!-- Dark mode -->
<my-component theme="dark">
  #shadow-root
    <div data-theme-root class="dark">
      <!-- Your component's rendered content -->
    </div>
</my-component>

Chain Definitions

Extended chain configurations for LUKSO networks with custom contracts and metadata.

import { luksoMainnet, luksoTestnet } from '@lukso/core/chains'

Types

Package contain some basic types.

import type { ChainExtended, NetworkSlug, Address } from '@lukso/core'

Configurations

Package provides some basic constants.

import { SUPPORTED_NETWORK_IDS, GRAPHQL_ENDPOINT_MAINNET, GRAPHQL_ENDPOINT_TESTNET } from '@lukso/core/config'

Using Without a Bundler (Import Maps)

If you need to use @lukso/core in environments without a bundler (e.g., plain HTML, WordPress, static sites), you can use import maps to resolve bare module specifiers.

Since this package uses Lit as a peer dependency and marks it as external, it outputs bare imports like import { html } from 'lit'. Browsers can't resolve these without help.

Example: Using Import Maps

<!DOCTYPE html>
<html>
<head>
  <script type="importmap">
    {
      "imports": {
        "lit": "https://cdn.jsdelivr.net/npm/lit@3.3/+esm",
        "lit/": "https://cdn.jsdelivr.net/npm/lit@3.3/",
        "@lit/reactive-element": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2/+esm",
        "@lit/reactive-element/": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2/",
        "@preact/signals-core": "https://cdn.jsdelivr.net/npm/@preact/signals-core@1/+esm",
        "@lukso/core": "https://cdn.jsdelivr.net/npm/@lukso/core/+esm",
        "@lukso/core/": "https://cdn.jsdelivr.net/npm/@lukso/core/"
      }
    }
  </script>
</head>
<body>
  <script type="module">
    import { deviceService } from '@lukso/core/services/device'
    import { luksoMainnet } from '@lukso/core/chains'

    const device = deviceService()
    console.log('Is mobile:', device.isMobile)
    console.log('Chain ID:', luksoMainnet.id)
  </script>
</body>
</html>

Notes on Import Maps

  • Browser Support: Import maps are supported in all modern browsers (Chrome 89+, Safari 16.4+, Firefox 108+)
  • Must be before scripts: The <script type="importmap"> must appear before any <script type="module">
  • Trailing slashes matter: Use "@lukso/core/" to map subpath imports like @lukso/core/services

License

MIT

Keywords

lukso

FAQs

Package last updated on 20 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts