WDK logoWDK documentation

WDK Utils Configuration

Install and import validation, encryption, mnemonic-sharing, key-derivation, and payment-request helpers from @tetherto/wdk-utils

This package does not have constructor options or runtime configuration. This page shows how to install @tetherto/wdk-utils, import the helpers you need, and understand the published runtime surface.

Install the package

You can install @tetherto/wdk-utils from npm:

Install @tetherto/wdk-utils
npm install @tetherto/wdk-utils

React Native runtimes without globalThis.crypto.getRandomValues also need a secure random-values polyfill:

Install React Native Random Values
npm install react-native-get-random-values

Load the polyfill before importing WDK Utils in the application entrypoint.

Import address validation helpers

You can import only the validators your flow needs from the package entrypoint:

Import Address Validators
import {
  validateAddress,
  validateBitcoinAddress,
  validateEVMAddress,
  validateLightningInvoice,
  validateLnurl,
  decodeLnurl,
  validateLightningAddress,
  validateSolanaAddress,
  validateSparkAddress,
  validateTronAddress,
  validateUmaAddress,
  resolveUmaUsername
} from '@tetherto/wdk-utils'

Import mnemonic sharing helpers

Split a valid English BIP-39 mnemonic into threshold shares and reconstruct it from enough shares:

Import Mnemonic Sharing Helpers
import {
  combineMnemonic,
  splitMnemonic
} from '@tetherto/wdk-utils'

Import EIP-681 helpers

You can detect and parse token transfer requests using the EIP-681 helpers:

Import EIP-681 Helpers
import {
  isEip681Request,
  parseEip681Request
} from '@tetherto/wdk-utils'

Import BIP-21 helpers

You can detect, parse, and encode Bitcoin payment URIs using the BIP-21 helpers:

Import BIP-21 Helpers
import {
  encodeBip21Request,
  isBip21Request,
  parseBip21Request
} from '@tetherto/wdk-utils'

Import seed encryption helpers

You can encrypt and decrypt seed phrases or other local strings with the AES-256-GCM helpers:

Import Seed Encryption Helpers
import {
  decrypt,
  decryptWithKey,
  deriveKey,
  encrypt
} from '@tetherto/wdk-utils'

Import seed key derivation helpers

Derive domain-separated byte keys or deterministic Ed25519 keypairs from high-entropy seed bytes:

Import Seed Key Derivation Helpers
import {
  deriveSeedKey,
  deriveSeedKeyPair
} from '@tetherto/wdk-utils'

Import BOLT11 helpers

You can validate, decode, sign, and encode BOLT11 Lightning invoices from the package entrypoint:

Import BOLT11 Helpers
import {
  decode as decodeBolt11,
  encode as encodeBolt11,
  getHashToSign,
  sign as signBolt11,
  validateLightningInvoice
} from '@tetherto/wdk-utils'

Runtime notes

  • @tetherto/wdk-utils exports plain functions. There is no client object to initialize.
  • The package publishes a default module entrypoint through index.js and a bare runtime entrypoint through bare.js.
  • validateAddress() dispatches the CAIP-2 namespaces bip122, eip155, solana, spark, and tron to their chain validators. Unsupported namespaces return UNSUPPORTED_CHAIN, and malformed chain IDs return INVALID_CHAIN_ID.
  • For bip122 and spark, the chain reference selects the expected network. A missing, unknown, or incompatible reference returns NETWORK_MISMATCH. Other supported namespaces validate the address format but do not enforce the reference value.
  • Successful Bitcoin and Spark validators return compatibleNetworks, because some address formats are valid on more than one network. WDK Utils validates structure and network compatibility, not account existence, ownership, or recipient intent.
  • validateSolanaAddress() accepts base58-encoded 32-byte public keys, including off-curve program-derived addresses. Solana has no address checksum, so the helper cannot detect every mistyped address.
  • splitMnemonic() accepts valid 12-, 15-, 18-, 21-, or 24-word English BIP-39 phrases. It returns hex-encoded Shamir shares and supports threshold schemes from 2-of-2 through 255-of-255.
  • combineMnemonic() verifies an embedded integrity checksum before returning the reconstructed phrase. The checksum detects corruption but does not authenticate shares.
  • encrypt() and splitMnemonic() require globalThis.crypto.getRandomValues. In React Native, load react-native-get-random-values before importing @tetherto/wdk-utils when the runtime does not provide secure random bytes.
  • parseBip21Request() accepts bitcoin: URIs with a validated Bitcoin address and optional amount, label, and message parameters.
  • encodeBip21Request() validates the Bitcoin address and amount before returning a bitcoin: URI.
  • encrypt() returns a versioned payload with hex-encoded salt, iv, tag, and ciphertext fields plus the scrypt cost parameters used for key derivation.
  • decrypt() reads the scrypt cost parameters from the encrypted payload when they are present.
  • deriveKey() returns a 32-byte Uint8Array key, and decryptWithKey() can reuse that key for decrypting a payload.
  • deriveSeedKey() uses HKDF-SHA256 and defaults to a 32-byte output. Both salt and info are required and are chosen by the caller; the package provides no built-in domain labels.
  • Pass high-entropy BIP-39 seed bytes to the seed key derivation helpers, not a mnemonic phrase. Accepted string inputs are consumed literally as UTF-8 and are not converted from mnemonic words into seed bytes.
  • deriveSeedKeyPair() always derives a 32-byte Ed25519 seed and returns a 32-byte publicKey plus a sensitive 64-byte secretKey, regardless of an options.length value.
  • BIP-21 amounts are decimal BTC strings with up to eight decimal places and a maximum value of 21000000.
  • BOLT11 helpers support invoices for bitcoin, testnet, regtest, and signet networks.
  • decode() returns user-provided invoice descriptions when they are present. Sanitize descriptions before rendering them in HTML or storing them.
  • decodeLnurl() returns the decoded URL string when parsing succeeds.
  • parseEip681Request() currently supports transfer requests for the schemes implemented in the published runtime: ethereum, pol, matic, polygon, arbitrum, and plasma.
  • parseEip681Request() accepts both uint256 and value query parameters for the amount field and normalizes the parsed amount into amountSmallest.

Examples

You can validate common wallet inputs before handing them to a module:

Validate Common Inputs
import {
  validateAddress,
  validateBitcoinAddress,
  validateLightningAddress,
  validateSolanaAddress,
  validateTronAddress,
  validateUmaAddress
} from '@tetherto/wdk-utils'

const chainAware = validateAddress(
  'bip122:000000000019d6689c085ae165831e93',
  '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'
)
const btc = validateBitcoinAddress('bc1qu9yqnhc6wjj6s62s9x0shnl5l2r7gq5cudm94r7mvwv0uw4s7acq0hn9g6')
const lightning = validateLightningAddress('sprycomfort92@waletofsatoshi.com')
const solana = validateSolanaAddress('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v')
const tron = validateTronAddress('TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH')
const uma = validateUmaAddress('$you@uma.money')

You can decode BOLT11 invoice details before presenting a payment request:

Decode A BOLT11 Invoice
import { decode as decodeBolt11 } from '@tetherto/wdk-utils'

const invoice = decodeBolt11(
  'lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w'
)

You can parse and encode a BIP-21 Bitcoin payment request:

Handle A BIP-21 Request
import { encodeBip21Request, parseBip21Request } from '@tetherto/wdk-utils'

const parsed = parseBip21Request(
  'bitcoin:1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH?amount=0.001&label=Coffee'
)

const encoded = encodeBip21Request({
  address: '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH',
  amount: '0.001',
  label: 'Coffee'
})

You can parse a request-shaped EIP-681 transfer string into structured data:

Parse An EIP-681 Transfer Request
import { parseEip681Request } from '@tetherto/wdk-utils'

const request = parseEip681Request(
  'pol:0xc2132D05D31c914a87C6611C10748AEb04B58e8F@137/transfer?address=0xA9e338082A061d657014c08e652D96B38639F22a&uint256=0.175309000e6'
)

You can protect a seed phrase with a passphrase before storing it in local app state:

Encrypt A Seed Phrase
import { decrypt, encrypt } from '@tetherto/wdk-utils'

const encrypted = encrypt(seedPhrase, passphrase)
const restoredSeedPhrase = decrypt(encrypted, passphrase)

You can split a BIP-39 mnemonic into shares that require a threshold to recover:

Split And Recover A Mnemonic
import 'react-native-get-random-values' // React Native only; load before WDK Utils
import { combineMnemonic, splitMnemonic } from '@tetherto/wdk-utils'

const shares = await splitMnemonic(seedPhrase, {
  shares: 5,
  threshold: 3
})

const restored = await combineMnemonic([
  shares[0],
  shares[2],
  shares[4]
])

Treat every unencrypted share as sensitive recovery material. Store shares separately and do not send them to logs, analytics, or untrusted services.

You can derive independent keys for application-specific purposes by using distinct domain labels:

Derive Domain-Separated Keys
import { deriveSeedKey, deriveSeedKeyPair } from '@tetherto/wdk-utils'

const syncKey = deriveSeedKey(seedBytes, {
  salt: 'com.example.wallet/v1',
  info: 'sync-encryption'
})

const signingKeyPair = deriveSeedKeyPair(seedBytes, {
  salt: 'com.example.wallet/v1',
  info: 'device-signing'
})

// Clear sensitive outputs after their final use.
syncKey.fill(0)
signingKeyPair.secretKey.fill(0)

Need Help?

On this page