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:
npm install @tetherto/wdk-utilsReact Native runtimes without globalThis.crypto.getRandomValues also need a secure random-values polyfill:
npm install react-native-get-random-valuesLoad 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 {
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 {
combineMnemonic,
splitMnemonic
} from '@tetherto/wdk-utils'Import EIP-681 helpers
You can detect and parse token transfer requests using the 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 {
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 {
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 {
deriveSeedKey,
deriveSeedKeyPair
} from '@tetherto/wdk-utils'Import BOLT11 helpers
You can validate, decode, sign, and encode BOLT11 Lightning invoices from the package entrypoint:
import {
decode as decodeBolt11,
encode as encodeBolt11,
getHashToSign,
sign as signBolt11,
validateLightningInvoice
} from '@tetherto/wdk-utils'Runtime notes
@tetherto/wdk-utilsexports plain functions. There is no client object to initialize.- The package publishes a default module entrypoint through
index.jsand a bare runtime entrypoint throughbare.js. validateAddress()dispatches the CAIP-2 namespacesbip122,eip155,solana,spark, andtronto their chain validators. Unsupported namespaces returnUNSUPPORTED_CHAIN, and malformed chain IDs returnINVALID_CHAIN_ID.- For
bip122andspark, the chain reference selects the expected network. A missing, unknown, or incompatible reference returnsNETWORK_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()andsplitMnemonic()requireglobalThis.crypto.getRandomValues. In React Native, loadreact-native-get-random-valuesbefore importing@tetherto/wdk-utilswhen the runtime does not provide secure random bytes.parseBip21Request()acceptsbitcoin:URIs with a validated Bitcoin address and optionalamount,label, andmessageparameters.encodeBip21Request()validates the Bitcoin address and amount before returning abitcoin:URI.encrypt()returns a versioned payload with hex-encodedsalt,iv,tag, andciphertextfields 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-byteUint8Arraykey, anddecryptWithKey()can reuse that key for decrypting a payload.deriveSeedKey()uses HKDF-SHA256 and defaults to a 32-byte output. Bothsaltandinfoare 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-bytepublicKeyplus a sensitive 64-bytesecretKey, regardless of anoptions.lengthvalue.- 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, andsignetnetworks. 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, andplasma.parseEip681Request()accepts bothuint256andvaluequery parameters for the amount field and normalizes the parsed amount intoamountSmallest.
Examples
You can validate common wallet inputs before handing them to a module:
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:
import { decode as decodeBolt11 } from '@tetherto/wdk-utils'
const invoice = decodeBolt11(
'lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w'
)You can parse and encode a BIP-21 Bitcoin payment 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:
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:
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:
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:
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)