UNPKG

@polkadot-labs/hdkd-helpers

Version:

Composable utility functions to generate key pairs for the sr25519, ed25519, and ecdsa cryptographic schemes, along with utilities for hierarchical deterministic (HD) key derivation, tailored for use in the Polkadot and Substrate ecosystems.

369 lines (348 loc) 27 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { BIP39_EN_WORDLIST: () => BIP39_EN_WORDLIST, DEV_MINI_SECRET: () => DEV_MINI_SECRET, DEV_PHRASE: () => DEV_PHRASE, accountId: () => accountId, blake2b256: () => blake2b256, blake2b512: () => blake2b512, createDerive: () => createDerive, createDeriveKeyPairFn: () => createDeriveKeyPairFn, ecdsa: () => ecdsa, ecdsaDerive: () => ecdsaDerive, ed25519: () => ed25519, ed25519Derive: () => ed25519Derive, ensureBytes: () => ensureBytes, entropyToMiniSecret: () => entropyToMiniSecret, entropyToMiniSecretAsync: () => entropyToMiniSecretAsync, entropyToMnemonic: () => entropyToMnemonic, generateMnemonic: () => generateMnemonic, mnemonicToEntropy: () => mnemonicToEntropy, mnemonicToMiniSecret: () => mnemonicToMiniSecret, mnemonicToMiniSecretAsync: () => mnemonicToMiniSecretAsync, parseSuri: () => parseSuri, sr25519: () => sr25519, sr25519Derive: () => sr25519Derive, ss58Address: () => ss58Address, ss58Decode: () => ss58Decode, ss58Encode: () => ss58Encode, ss58PublicKey: () => ss58PublicKey, validateMnemonic: () => validateMnemonic }); module.exports = __toCommonJS(index_exports); // src/constants.ts var DEV_PHRASE = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; var DEV_MINI_SECRET = "fac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"; // src/utils.ts var import_utils = require("@noble/curves/abstract/utils"); var import_blake2b = require("@noble/hashes/blake2b"); var import_scale_ts = require("scale-ts"); var blake2b256 = (msg) => (0, import_blake2b.blake2b)(msg, { dkLen: 32 }); var blake2b512 = (msg) => (0, import_blake2b.blake2b)(msg, { dkLen: 64 }); var ensureBytes = (title, hex, expectedLength) => { if (typeof hex === "string" && hex[1] === "x") hex = hex.slice(2); return (0, import_utils.ensureBytes)(title, hex, expectedLength); }; var derivationCodec = /* @__PURE__ */ (0, import_scale_ts.Tuple)(import_scale_ts.str, (0, import_scale_ts.Bytes)(32), (0, import_scale_ts.Bytes)(32)); var createDeriveFn = (prefix) => (seed, chainCode) => blake2b256(derivationCodec.enc([prefix, seed, chainCode])); var createDeriveKeyPairFn = (prefix) => (seed, curve, derivations) => { const derive = createDeriveFn(prefix); const privateKey = derivations.reduce((seed2, [type, chainCode]) => { if (type === "soft") throw new Error("Soft derivations are not supported"); return derive(seed2, chainCode); }, seed); return { publicKey: curve.getPublicKey(privateKey), sign(message) { return curve.sign(message, privateKey); } }; }; // src/accountId.ts var VALID_PUBLICKEY_LENGTHS = [32, 33]; var accountId = (publicKey) => { publicKey = ensureBytes("publicKey", publicKey); if (!VALID_PUBLICKEY_LENGTHS.includes(publicKey.length)) throw new Error("Invalid publicKey"); return publicKey.length === 33 ? blake2b256(publicKey) : publicKey; }; // src/ss58/ss58.ts var import_base = require("@scure/base"); var SS58PRE = /* @__PURE__ */ new TextEncoder().encode("SS58PRE"); var CHECKSUM_LENGTH = 2; var VALID_PAYLOAD_LENGTHS = [32, 33]; var ss58Encode = (payload, prefix = 42) => { payload = ensureBytes("payload", payload); if (!VALID_PAYLOAD_LENGTHS.includes(payload.length)) throw new Error("Invalid payload"); const prefixBytes = prefix < 64 ? Uint8Array.of(prefix) : Uint8Array.of( (prefix & 252) >> 2 | 64, prefix >> 8 | (prefix & 3) << 6 ); const checksum = blake2b512( Uint8Array.of(...SS58PRE, ...prefixBytes, ...payload) ).subarray(0, CHECKSUM_LENGTH); return import_base.base58.encode(Uint8Array.of(...prefixBytes, ...payload, ...checksum)); }; var VALID_ADDRESS_LENGTHS = [35, 36, 37]; var ss58Decode = (addressStr) => { const address = import_base.base58.decode(addressStr); if (!VALID_ADDRESS_LENGTHS.includes(address.length)) throw new Error("Invalid address length"); const addressChecksum = address.subarray(address.length - CHECKSUM_LENGTH); const checksum = blake2b512( Uint8Array.of( ...SS58PRE, ...address.subarray(0, address.length - CHECKSUM_LENGTH) ) ).subarray(0, CHECKSUM_LENGTH); if (addressChecksum[0] !== checksum[0] || addressChecksum[1] !== checksum[1]) throw new Error("Invalid checksum"); const prefixLength = address[0] & 64 ? 2 : 1; const prefix = prefixLength === 1 ? address[0] : (address[0] & 63) << 2 | address[1] >> 6 | (address[1] & 63) << 8; const payload = address.slice(prefixLength, address.length - CHECKSUM_LENGTH); return [payload, prefix]; }; // src/ss58/ss58Address.ts var ss58Address = (publicKey, prefix = 42) => ss58Encode(accountId(publicKey), prefix); // src/ss58/ss58PublicKey.ts var ss58PublicKey = ss58Encode; // src/bip39.ts var import_sha256 = require("@noble/hashes/sha256"); var import_utils3 = require("@noble/hashes/utils"); // src/bip39EnWordlist.ts var BIP39_EN_WORDLIST = "abandon|ability|able|about|above|absent|absorb|abstract|absurd|abuse|access|accident|account|accuse|achieve|acid|acoustic|acquire|across|act|action|actor|actress|actual|adapt|add|addict|address|adjust|admit|adult|advance|advice|aerobic|affair|afford|afraid|again|age|agent|agree|ahead|aim|air|airport|aisle|alarm|album|alcohol|alert|alien|all|alley|allow|almost|alone|alpha|already|also|alter|always|amateur|amazing|among|amount|amused|analyst|anchor|ancient|anger|angle|angry|animal|ankle|announce|annual|another|answer|antenna|antique|anxiety|any|apart|apology|appear|apple|approve|april|arch|arctic|area|arena|argue|arm|armed|armor|army|around|arrange|arrest|arrive|arrow|art|artefact|artist|artwork|ask|aspect|assault|asset|assist|assume|asthma|athlete|atom|attack|attend|attitude|attract|auction|audit|august|aunt|author|auto|autumn|average|avocado|avoid|awake|aware|away|awesome|awful|awkward|axis|baby|bachelor|bacon|badge|bag|balance|balcony|ball|bamboo|banana|banner|bar|barely|bargain|barrel|base|basic|basket|battle|beach|bean|beauty|because|become|beef|before|begin|behave|behind|believe|below|belt|bench|benefit|best|betray|better|between|beyond|bicycle|bid|bike|bind|biology|bird|birth|bitter|black|blade|blame|blanket|blast|bleak|bless|blind|blood|blossom|blouse|blue|blur|blush|board|boat|body|boil|bomb|bone|bonus|book|boost|border|boring|borrow|boss|bottom|bounce|box|boy|bracket|brain|brand|brass|brave|bread|breeze|brick|bridge|brief|bright|bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden|burger|burst|bus|business|busy|butter|buyer|buzz|cabbage|cabin|cable|cactus|cage|cake|call|calm|camera|camp|can|canal|cancel|candy|cannon|canoe|canvas|canyon|capable|capital|captain|car|carbon|card|cargo|carpet|carry|cart|case|cash|casino|castle|casual|cat|catalog|catch|category|cattle|caught|cause|caution|cave|ceiling|celery|cement|census|century|cereal|certain|chair|chalk|champion|change|chaos|chapter|charge|chase|chat|cheap|check|cheese|chef|cherry|chest|chicken|chief|child|chimney|choice|choose|chronic|chuckle|chunk|churn|cigar|cinnamon|circle|citizen|city|civil|claim|clap|clarify|claw|clay|clean|clerk|clever|click|client|cliff|climb|clinic|clip|clock|clog|close|cloth|cloud|clown|club|clump|cluster|clutch|coach|coast|coconut|code|coffee|coil|coin|collect|color|column|combine|come|comfort|comic|common|company|concert|conduct|confirm|congress|connect|consider|control|convince|cook|cool|copper|copy|coral|core|corn|correct|cost|cotton|couch|country|couple|course|cousin|cover|coyote|crack|cradle|craft|cram|crane|crash|crater|crawl|crazy|cream|credit|creek|crew|cricket|crime|crisp|critic|crop|cross|crouch|crowd|crucial|cruel|cruise|crumble|crunch|crush|cry|crystal|cube|culture|cup|cupboard|curious|current|curtain|curve|cushion|custom|cute|cycle|dad|damage|damp|dance|danger|daring|dash|daughter|dawn|day|deal|debate|debris|decade|december|decide|decline|decorate|decrease|deer|defense|define|defy|degree|delay|deliver|demand|demise|denial|dentist|deny|depart|depend|deposit|depth|deputy|derive|describe|desert|design|desk|despair|destroy|detail|detect|develop|device|devote|diagram|dial|diamond|diary|dice|diesel|diet|differ|digital|dignity|dilemma|dinner|dinosaur|direct|dirt|disagree|discover|disease|dish|dismiss|disorder|display|distance|divert|divide|divorce|dizzy|doctor|document|dog|doll|dolphin|domain|donate|donkey|donor|door|dose|double|dove|draft|dragon|drama|drastic|draw|dream|dress|drift|drill|drink|drip|drive|drop|drum|dry|duck|dumb|dune|during|dust|dutch|duty|dwarf|dynamic|eager|eagle|early|earn|earth|easily|east|easy|echo|ecology|economy|edge|edit|educate|effort|egg|eight|either|elbow|elder|electric|elegant|element|elephant|elevator|elite|else|embark|embody|embrace|emerge|emotion|employ|empower|empty|enable|enact|end|endless|endorse|enemy|energy|enforce|engage|engine|enhance|enjoy|enlist|enough|enrich|enroll|ensure|enter|entire|entry|envelope|episode|equal|equip|era|erase|erode|erosion|error|erupt|escape|essay|essence|estate|eternal|ethics|evidence|evil|evoke|evolve|exact|example|excess|exchange|excite|exclude|excuse|execute|exercise|exhaust|exhibit|exile|exist|exit|exotic|expand|expect|expire|explain|expose|express|extend|extra|eye|eyebrow|fabric|face|faculty|fade|faint|faith|fall|false|fame|family|famous|fan|fancy|fantasy|farm|fashion|fat|fatal|father|fatigue|fault|favorite|feature|february|federal|fee|feed|feel|female|fence|festival|fetch|fever|few|fiber|fiction|field|figure|file|film|filter|final|find|fine|finger|finish|fire|firm|first|fiscal|fish|fit|fitness|fix|flag|flame|flash|flat|flavor|flee|flight|flip|float|flock|floor|flower|fluid|flush|fly|foam|focus|fog|foil|fold|follow|food|foot|force|forest|forget|fork|fortune|forum|forward|fossil|foster|found|fox|fragile|frame|frequent|fresh|friend|fringe|frog|front|frost|frown|frozen|fruit|fuel|fun|funny|furnace|fury|future|gadget|gain|galaxy|gallery|game|gap|garage|garbage|garden|garlic|garment|gas|gasp|gate|gather|gauge|gaze|general|genius|genre|gentle|genuine|gesture|ghost|giant|gift|giggle|ginger|giraffe|girl|give|glad|glance|glare|glass|glide|glimpse|globe|gloom|glory|glove|glow|glue|goat|goddess|gold|good|goose|gorilla|gospel|gossip|govern|gown|grab|grace|grain|grant|grape|grass|gravity|great|green|grid|grief|grit|grocery|group|grow|grunt|guard|guess|guide|guilt|guitar|gun|gym|habit|hair|half|hammer|hamster|hand|happy|harbor|hard|harsh|harvest|hat|have|hawk|hazard|head|health|heart|heavy|hedgehog|height|hello|helmet|help|hen|hero|hidden|high|hill|hint|hip|hire|history|hobby|hockey|hold|hole|holiday|hollow|home|honey|hood|hope|horn|horror|horse|hospital|host|hotel|hour|hover|hub|huge|human|humble|humor|hundred|hungry|hunt|hurdle|hurry|hurt|husband|hybrid|ice|icon|idea|identify|idle|ignore|ill|illegal|illness|image|imitate|immense|immune|impact|impose|improve|impulse|inch|include|income|increase|index|indicate|indoor|industry|infant|inflict|inform|inhale|inherit|initial|inject|injury|inmate|inner|innocent|input|inquiry|insane|insect|inside|inspire|install|intact|interest|into|invest|invite|involve|iron|island|isolate|issue|item|ivory|jacket|jaguar|jar|jazz|jealous|jeans|jelly|jewel|job|join|joke|journey|joy|judge|juice|jump|jungle|junior|junk|just|kangaroo|keen|keep|ketchup|key|kick|kid|kidney|kind|kingdom|kiss|kit|kitchen|kite|kitten|kiwi|knee|knife|knock|know|lab|label|labor|ladder|lady|lake|lamp|language|laptop|large|later|latin|laugh|laundry|lava|law|lawn|lawsuit|layer|lazy|leader|leaf|learn|leave|lecture|left|leg|legal|legend|leisure|lemon|lend|length|lens|leopard|lesson|letter|level|liar|liberty|library|license|life|lift|light|like|limb|limit|link|lion|liquid|list|little|live|lizard|load|loan|lobster|local|lock|logic|lonely|long|loop|lottery|loud|lounge|love|loyal|lucky|luggage|lumber|lunar|lunch|luxury|lyrics|machine|mad|magic|magnet|maid|mail|main|major|make|mammal|man|manage|mandate|mango|mansion|manual|maple|marble|march|margin|marine|market|marriage|mask|mass|master|match|material|math|matrix|matter|maximum|maze|meadow|mean|measure|meat|mechanic|medal|media|melody|melt|member|memory|mention|menu|mercy|merge|merit|merry|mesh|message|metal|method|middle|midnight|milk|million|mimic|mind|minimum|minor|minute|miracle|mirror|misery|miss|mistake|mix|mixed|mixture|mobile|model|modify|mom|moment|monitor|monkey|monster|month|moon|moral|more|morning|mosquito|mother|motion|motor|mountain|mouse|move|movie|much|muffin|mule|multiply|muscle|museum|mushroom|music|must|mutual|myself|mystery|myth|naive|name|napkin|narrow|nasty|nation|nature|near|neck|need|negative|neglect|neither|nephew|nerve|nest|net|network|neutral|never|news|next|nice|night|noble|noise|nominee|noodle|normal|north|nose|notable|note|nothing|notice|novel|now|nuclear|number|nurse|nut|oak|obey|object|oblige|obscure|observe|obtain|obvious|occur|ocean|october|odor|off|offer|office|often|oil|okay|old|olive|olympic|omit|once|one|onion|online|only|open|opera|opinion|oppose|option|orange|orbit|orchard|order|ordinary|organ|orient|original|orphan|ostrich|other|outdoor|outer|output|outside|oval|oven|over|own|owner|oxygen|oyster|ozone|pact|paddle|page|pair|palace|palm|panda|panel|panic|panther|paper|parade|parent|park|parrot|party|pass|patch|path|patient|patrol|pattern|pause|pave|payment|peace|peanut|pear|peasant|pelican|pen|penalty|pencil|people|pepper|perfect|permit|person|pet|phone|photo|phrase|physical|piano|picnic|picture|piece|pig|pigeon|pill|pilot|pink|pioneer|pipe|pistol|pitch|pizza|place|planet|plastic|plate|play|please|pledge|pluck|plug|plunge|poem|poet|point|polar|pole|police|pond|pony|pool|popular|portion|position|possible|post|potato|pottery|poverty|powder|power|practice|praise|predict|prefer|prepare|present|pretty|prevent|price|pride|primary|print|priority|prison|private|prize|problem|process|produce|profit|program|project|promote|proof|property|prosper|protect|proud|provide|public|pudding|pull|pulp|pulse|pumpkin|punch|pupil|puppy|purchase|purity|purpose|purse|push|put|puzzle|pyramid|quality|quantum|quarter|question|quick|quit|quiz|quote|rabbit|raccoon|race|rack|radar|radio|rail|rain|raise|rally|ramp|ranch|random|range|rapid|rare|rate|rather|raven|raw|razor|ready|real|reason|rebel|rebuild|recall|receive|recipe|record|recycle|reduce|reflect|reform|refuse|region|regret|regular|reject|relax|release|relief|rely|remain|remember|remind|remove|render|renew|rent|reopen|repair|repeat|replace|report|require|rescue|resemble|resist|resource|response|result|retire|retreat|return|reunion|reveal|review|reward|rhythm|rib|ribbon|rice|rich|ride|ridge|rifle|right|rigid|ring|riot|ripple|risk|ritual|rival|river|road|roast|robot|robust|rocket|romance|roof|rookie|room|rose|rotate|rough|round|route|royal|rubber|rude|rug|rule|run|runway|rural|sad|saddle|sadness|safe|sail|salad|salmon|salon|salt|salute|same|sample|sand|satisfy|satoshi|sauce|sausage|save|say|scale|scan|scare|scatter|scene|scheme|school|science|scissors|scorpion|scout|scrap|screen|script|scrub|sea|search|season|seat|second|secret|section|security|seed|seek|segment|select|sell|seminar|senior|sense|sentence|series|service|session|settle|setup|seven|shadow|shaft|shallow|share|shed|shell|sheriff|shield|shift|shine|ship|shiver|shock|shoe|shoot|shop|short|shoulder|shove|shrimp|shrug|shuffle|shy|sibling|sick|side|siege|sight|sign|silent|silk|silly|silver|similar|simple|since|sing|siren|sister|situate|six|size|skate|sketch|ski|skill|skin|skirt|skull|slab|slam|sleep|slender|slice|slide|slight|slim|slogan|slot|slow|slush|small|smart|smile|smoke|smooth|snack|snake|snap|sniff|snow|soap|soccer|social|sock|soda|soft|solar|soldier|solid|solution|solve|someone|song|soon|sorry|sort|soul|sound|soup|source|south|space|spare|spatial|spawn|speak|special|speed|spell|spend|sphere|spice|spider|spike|spin|spirit|split|spoil|sponsor|spoon|sport|spot|spray|spread|spring|spy|square|squeeze|squirrel|stable|stadium|staff|stage|stairs|stamp|stand|start|state|stay|steak|steel|stem|step|stereo|stick|still|sting|stock|stomach|stone|stool|story|stove|strategy|street|strike|strong|struggle|student|stuff|stumble|style|subject|submit|subway|success|such|sudden|suffer|sugar|suggest|suit|summer|sun|sunny|sunset|super|supply|supreme|sure|surface|surge|surprise|surround|survey|suspect|sustain|swallow|swamp|swap|swarm|swear|sweet|swift|swim|swing|switch|sword|symbol|symptom|syrup|system|table|tackle|tag|tail|talent|talk|tank|tape|target|task|taste|tattoo|taxi|teach|team|tell|ten|tenant|tennis|tent|term|test|text|thank|that|theme|then|theory|there|they|thing|this|thought|three|thrive|throw|thumb|thunder|ticket|tide|tiger|tilt|timber|time|tiny|tip|tired|tissue|title|toast|tobacco|today|toddler|toe|together|toilet|token|tomato|tomorrow|tone|tongue|tonight|tool|tooth|top|topic|topple|torch|tornado|tortoise|toss|total|tourist|toward|tower|town|toy|track|trade|traffic|tragic|train|transfer|trap|trash|travel|tray|treat|tree|trend|trial|tribe|trick|trigger|trim|trip|trophy|trouble|truck|true|truly|trumpet|trust|truth|try|tube|tuition|tumble|tuna|tunnel|turkey|turn|turtle|twelve|twenty|twice|twin|twist|two|type|typical|ugly|umbrella|unable|unaware|uncle|uncover|under|undo|unfair|unfold|unhappy|uniform|unique|unit|universe|unknown|unlock|until|unusual|unveil|update|upgrade|uphold|upon|upper|upset|urban|urge|usage|use|used|useful|useless|usual|utility|vacant|vacuum|vague|valid|valley|valve|van|vanish|vapor|various|vast|vault|vehicle|velvet|vendor|venture|venue|verb|verify|version|very|vessel|veteran|viable|vibrant|vicious|victory|video|view|village|vintage|violin|virtual|virus|visa|visit|visual|vital|vivid|vocal|voice|void|volcano|volume|vote|voyage|wage|wagon|wait|walk|wall|walnut|want|warfare|warm|warrior|wash|wasp|waste|water|wave|way|wealth|weapon|wear|weasel|weather|web|wedding|weekend|weird|welcome|west|wet|whale|what|wheat|wheel|when|where|whip|whisper|wide|width|wife|wild|will|win|window|wine|wing|wink|winner|winter|wire|wisdom|wise|wish|witness|wolf|woman|wonder|wood|wool|word|work|world|worry|worth|wrap|wreck|wrestle|wrist|write|wrong|yard|year|yellow|you|young|youth|zebra|zero|zone|zoo"; // src/bip39.ts var INVALID_MNEMONIC = "Invalid mnemonic"; var INVALID_ENTROPY = "Invalid entropy"; var INVALID_CHECKSUM = "Invalid mnemonic checksum"; var WORDLIST_REQUIRED = "Invalid wordlist"; var parseWordlist = (wordlistStr) => { const wordlist = wordlistStr.split("|"); if (wordlist.length !== 2048) throw new Error(WORDLIST_REQUIRED); return wordlist; }; var deriveChecksumBits = (entropy) => (0, import_sha256.sha256)(entropy)[0].toString(2).padStart(8, "0").slice(0, entropy.length / 4); var mnemonicToEntropy = (mnemonic, wordlistStr = BIP39_EN_WORDLIST) => { const words = mnemonic.normalize("NFKD").split(" "); if (words.length % 3 !== 0 || words.length < 12 || words.length > 24) throw new Error(INVALID_MNEMONIC); const wordlist = parseWordlist(wordlistStr); const bits = words.map((word) => { const index = wordlist.indexOf(word); if (index === -1) throw new Error(INVALID_MNEMONIC); return index.toString(2).padStart(11, "0"); }).join(""); const dividerIndex = bits.length - words.length / 3; const entropyBytes = bits.slice(0, dividerIndex).match(/(.{1,8})/g)?.map((bin) => Number.parseInt(bin, 2)); if (!entropyBytes || entropyBytes.length < 16 || entropyBytes.length > 32 || entropyBytes.length % 4 !== 0) throw new Error(INVALID_ENTROPY); const entropy = Uint8Array.from(entropyBytes); if (deriveChecksumBits(entropy) !== bits.slice(dividerIndex)) throw new Error(INVALID_CHECKSUM); return entropy; }; var entropyToMnemonic = (entropy, wordlistStr = BIP39_EN_WORDLIST) => { const wordlist = parseWordlist(wordlistStr); if (!wordlist || wordlist.length !== 2048) throw new Error(WORDLIST_REQUIRED); if (entropy.length < 16 || entropy.length > 32 || entropy.length % 4 !== 0) throw new TypeError(INVALID_ENTROPY); const entropyBits = Array.from(entropy).map((byte) => byte.toString(2).padStart(8, "0")).join(""); return (entropyBits + deriveChecksumBits(entropy)).match(/(.{1,11})/g).map((binary) => wordlist[Number.parseInt(binary, 2)]).join(" "); }; var generateMnemonic = (strength = 128, wordlist = BIP39_EN_WORDLIST) => entropyToMnemonic((0, import_utils3.randomBytes)(strength / 8), wordlist); var validateMnemonic = (mnemonic, wordlist = BIP39_EN_WORDLIST) => { try { mnemonicToEntropy(mnemonic, wordlist); } catch (e) { return false; } return true; }; // src/substrateBip39.ts var import_pbkdf2 = require("@noble/hashes/pbkdf2"); var import_sha512 = require("@noble/hashes/sha512"); var salt = (password) => new TextEncoder().encode(`mnemonic${password.normalize("NFKD")}`); var entropyToMiniSecret = (entropy, password = "") => (0, import_pbkdf2.pbkdf2)(import_sha512.sha512, entropy, salt(password), { c: 2048, dkLen: 64 }).slice(0, 32); var entropyToMiniSecretAsync = async (entropy, password = "") => (await (0, import_pbkdf2.pbkdf2Async)(import_sha512.sha512, entropy, salt(password), { c: 2048, dkLen: 64 })).slice(0, 32); var mnemonicToMiniSecret = (mnemonic, password = "", wordlist = BIP39_EN_WORDLIST) => entropyToMiniSecret(mnemonicToEntropy(mnemonic, wordlist), password); var mnemonicToMiniSecretAsync = (mnemonic, password = "", wordlist = BIP39_EN_WORDLIST) => entropyToMiniSecretAsync(mnemonicToEntropy(mnemonic, wordlist), password); // src/parseSuri.ts var SURI_RE = /^(\w+(?: \w+)*)((?:\/{1,2}\w+)*)(?:\/{3}(.*))?$/; var parseSuri = (suri) => { const [, phrase, paths, password] = SURI_RE.exec(suri) ?? []; return { phrase, paths, password }; }; // src/ecdsa.ts var import_secp256k1 = require("@noble/curves/secp256k1"); var ecdsa = { getPublicKey(privateKey) { return import_secp256k1.secp256k1.getPublicKey(ensureBytes("privateKey", privateKey)); }, sign(message, privateKey) { const signature = import_secp256k1.secp256k1.sign( blake2b256(ensureBytes("message", message)), ensureBytes("privateKey", privateKey) ); const signedBytes = signature.toCompactRawBytes(); const out = new Uint8Array(signedBytes.length + 1); out.set(signedBytes); out[signedBytes.length] = signature.recovery; return out; }, verify(signature, message, publicKey) { return import_secp256k1.secp256k1.verify( import_secp256k1.secp256k1.Signature.fromCompact( ensureBytes("signature", signature).slice(0, 64) ), blake2b256(ensureBytes("message", message)), ensureBytes("publicKey", publicKey) ); } }; // src/ed25519.ts var import_ed25519 = require("@noble/curves/ed25519"); var ed25519 = { getPublicKey(privateKey) { return import_ed25519.ed25519.getPublicKey(ensureBytes("privateKey", privateKey)); }, sign(message, privateKey) { return import_ed25519.ed25519.sign( ensureBytes("message", message), ensureBytes("privateKey", privateKey) ); }, verify(signature, message, publicKey) { return import_ed25519.ed25519.verify( ensureBytes("signature", signature), ensureBytes("message", message), ensureBytes("privateKey", publicKey) ); } }; // src/sr25519.ts var import_micro_sr25519 = require("micro-sr25519"); var sr25519 = { getPublicKey(privateKey) { return (0, import_micro_sr25519.getPublicKey)(ensureBytes("privateKey", privateKey, 64)); }, sign(message, privateKey) { return (0, import_micro_sr25519.sign)( ensureBytes("privateKey", privateKey, 64), ensureBytes("message", message) ); }, verify(signature, message, publicKey) { return (0, import_micro_sr25519.verify)( ensureBytes("message", message), ensureBytes("signature", signature, 64), ensureBytes("publicKey", publicKey, 32) ); } }; // src/ecdsaDerive.ts var ecdsaDerive = /* @__PURE__ */ createDeriveKeyPairFn("Secp256k1HDKD"); // src/ed25519Derive.ts var ed25519Derive = /* @__PURE__ */ createDeriveKeyPairFn("Ed25519HDKD"); // src/sr25519Derive.ts var import_utils8 = require("@noble/hashes/utils"); var import_micro_sr255192 = require("micro-sr25519"); var sr25519Derive = (seed, curve, derivations) => { const privateKey = derivations.reduce( (secretKey, [type, chainCode]) => type === "hard" ? import_micro_sr255192.HDKD.secretHard(secretKey, chainCode) : import_micro_sr255192.HDKD.secretSoft(secretKey, chainCode, import_utils8.randomBytes), (0, import_micro_sr255192.secretFromSeed)(seed) ); const publicKey = (0, import_micro_sr255192.getPublicKey)(privateKey); return { publicKey, sign(message) { return curve.sign(message, privateKey); } }; }; // src/createChainCode.ts var import_scale_ts2 = require("scale-ts"); var createChainCode = (code) => { const chainCode = new Uint8Array(32); chainCode.set(Number.isNaN(+code) ? import_scale_ts2.str.enc(code) : import_scale_ts2.u32.enc(+code)); return chainCode; }; // src/parseDerivations.ts var DERIVATION_RE = /(\/{1,2})([^\/]+)/g; var parseDerivations = (derivationsStr) => { const derivations = []; for (const [_, type, code] of derivationsStr.matchAll(DERIVATION_RE)) { derivations.push([type === "//" ? "hard" : "soft", code]); } return derivations; }; // src/createDerive.ts var createDerive = ({ seed, curve, derive }) => (path) => derive( ensureBytes("seed", seed, 32), { getPublicKey: (privateKey) => curve.getPublicKey(privateKey), sign: (message, privateKey) => curve.sign(message, privateKey), verify: (signature, message, publicKey) => curve.verify(signature, message, publicKey) }, parseDerivations(path).map(([type, code]) => [ type, createChainCode(code) ]) ); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { BIP39_EN_WORDLIST, DEV_MINI_SECRET, DEV_PHRASE, accountId, blake2b256, blake2b512, createDerive, createDeriveKeyPairFn, ecdsa, ecdsaDerive, ed25519, ed25519Derive, ensureBytes, entropyToMiniSecret, entropyToMiniSecretAsync, entropyToMnemonic, generateMnemonic, mnemonicToEntropy, mnemonicToMiniSecret, mnemonicToMiniSecretAsync, parseSuri, sr25519, sr25519Derive, ss58Address, ss58Decode, ss58Encode, ss58PublicKey, validateMnemonic }); //# sourceMappingURL=index.cjs.map