npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@drakkar.software/dk-spaces-platform-sdk

v0.3.5

Published

Platform adapters for dk-spaces-sdk — KV, vault storage, passkey, and crypto setup.

Readme

@drakkar.software/dk-spaces-platform-sdk

Platform adapters for @drakkar.software/dk-spaces-sdk — KV persistence, vault storage (PIN + WebAuthn passkey), crypto setup, and an Argon2id shim for React Native.

Installation

pnpm add @drakkar.software/dk-spaces-platform-sdk @drakkar.software/dk-spaces-sdk

Optional native peer deps (Expo / React Native only):

npx expo install expo-secure-store @react-native-async-storage/async-storage react-native-quick-crypto

Overview

dk-spaces-sdk is platform-agnostic and ships no I/O. This package bridges it to the host environment:

| Concern | Web | Native | |---------|-----|--------| | Crypto | WebCrypto (built-in, no-op setup) | react-native-quick-crypto install | | KV store | localStorage | AsyncStorage | | Vault storage | AES-GCM + Argon2id PIN / WebAuthn PRF | expo-secure-store (OS keychain) | | Passkeys | WebAuthn PRF | stubs (always false / throws) | | Argon2id | hash-wasm (WASM) | pure-JS shim via @noble/hashes |

Metro resolves .native.ts automatically — no conditional imports needed in app code.

Setup

Call once at app boot before any SDK API:

// Web
import { configureStarfishPlatform, kvGet, kvSet, kvRemove } from '@drakkar.software/dk-spaces-platform-sdk'
import { configureKv } from '@drakkar.software/dk-spaces-sdk'

configureStarfishPlatform()
configureKv({ get: kvGet, set: kvSet, remove: kvRemove })
// Native (same imports — Metro picks index.native.ts)
import { configureStarfishPlatform, kvGet, kvSet, kvRemove } from '@drakkar.software/dk-spaces-platform-sdk'
import { configureKv } from '@drakkar.software/dk-spaces-sdk'

configureStarfishPlatform() // installs react-native-quick-crypto
configureKv({ get: kvGet, set: kvSet, remove: kvRemove })

Vault storage

The vault holds all local accounts under a single encrypted envelope. Unlock once, switch accounts freely without re-running Argon2id.

Web

AES-GCM encryption with a Vault Master Key (VMK) held in a closure after unlock. The VMK can be sealed under a PIN (Argon2id-stretched) and/or a WebAuthn PRF passkey secret.

import { createVaultStorage } from '@drakkar.software/dk-spaces-platform-sdk'

const vaultStorage = createVaultStorage({ storageKey: 'myapp.session.v1' })

// Load existing vault
const state = await vaultStorage.loadVault()
// state.kind: 'none' | 'locked' | 'ready'

// Unlock with PIN
const vault = await vaultStorage.unlockVault('pin', myPin)

// Save with PIN protection
await vaultStorage.saveVault(vault, { pin: myPin })

// Add passkey unlock after enrollment
await vaultStorage.addPasskeyToVault(enrollment)

// Unlock with passkey
const vault = await vaultStorage.unlockVault('passkey')

Warning: The storageKey is load-bearing. Changing it after deployment locks existing users out of their vaults.

Native

expo-secure-store (OS Keychain / Android Keystore) handles encryption at rest. No PIN or VMK required — loadVault() always returns { kind: 'ready' }.

import { createVaultStorageNative } from '@drakkar.software/dk-spaces-platform-sdk'

const vaultStorage = createVaultStorageNative()
const { vault } = await vaultStorage.loadVault()
await vaultStorage.saveVault(updatedVault)

Passkeys (web only)

WebAuthn PRF extension — derives a stable 32-byte secret from a hardware authenticator, used to seal the VMK without a PIN.

import { passkeySupported, passkeyEnrollable, enrollPasskey, evalPasskey } from '@drakkar.software/dk-spaces-platform-sdk'

if (await passkeyEnrollable()) {
  const { credentialId, salt, secretHex } = await enrollPasskey('Alice', 'My App', 'myapp')
  // store credentialId + salt; secretHex seals the VMK
}

// Later, to unlock:
const { secretHex } = await evalPasskey(credentialId, saltHex)

On native all passkey functions return false or throw — biometric auth is handled at the OS level by expo-secure-store.

Argon2id progress

PIN-based vault unlock runs Argon2id, which can take 30–120 seconds on slower devices. Subscribe to progress events to drive a UI indicator:

import { subscribeArgon2Progress } from '@drakkar.software/dk-spaces-platform-sdk'

const unsubscribe = subscribeArgon2Progress((pct) => {
  setProgress(pct) // 0–100
})
// call unsubscribe() when the unlock completes

hash-wasm shim (React Native / Hermes)

Hermes does not ship WebAssembly, so hash-wasm's Argon2id cannot run. Add a Metro resolver alias to redirect all hash-wasm imports to the pure-JS shim (byte-identical output via @noble/hashes):

// metro.config.js
config.resolver.resolveRequest = (ctx, mod, plat) => {
  if (mod === 'hash-wasm') {
    return {
      type: 'sourceFile',
      filePath: require.resolve('@drakkar.software/dk-spaces-platform-sdk/hash-wasm-shim'),
    }
  }
  return ctx.resolveRequest(ctx, mod, plat)
}

Security notes

  • Seeds are never stored in cleartext. The web vault wraps them in AES-GCM under an Argon2id-stretched PIN and/or a WebAuthn PRF secret.
  • All cryptographic operations happen client-side. The server stores only opaque ciphertext.
  • After unlock the VMK lives in a closure, not in React state or sessionStorage — account mutations are fast (one AES-GCM op) without re-running Argon2id.

ESM only

This package ships ESM only. Requires a bundler (Vite, Metro, etc.).

Changelog

See CHANGELOG.md.