UNPKG

@planetarium/account-web3-secret-storage

Version:

Libplanet account implementation using Ethereum Web3 Secret Storage

8 lines (7 loc) 40.5 kB
{ "version": 3, "sources": ["../src/index.ts", "../src/crypto/node.ts", "../src/KeyId.ts", "../src/TtyPassphraseEntry.ts", "../src/Web3Account.ts", "../src/Web3KeyStore.ts", "../src/path/node.ts", "../src/fs/node.ts"], "sourcesContent": ["export { KeyId } from \"./KeyId.js\";\nexport { PassphraseEntry } from \"./PassphraseEntry.js\";\nexport { TtyPassphraseEntry } from \"./TtyPassphraseEntry.js\";\nexport {\n type Web3AccountOptions as DecryptionOptions,\n WeakPrivateKeyError,\n Web3Account,\n type Web3KeyObject,\n} from \"./Web3Account.js\";\nexport {\n getDefaultWeb3KeyStorePath,\n Web3KeyStore,\n} from \"./Web3KeyStore.js\";\n", "import { Crypto } from \"@peculiar/webcrypto\";\nexport const crypto = new Crypto();\n", "import { crypto } from \"#crypto\";\n\nexport type KeyId = string;\n\nconst UUID_PATTERN =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function isKeyId(keyId: string): keyId is KeyId {\n return !!keyId.match(UUID_PATTERN);\n}\n\nexport function generateKeyId(): KeyId {\n return crypto.randomUUID();\n}\n\nexport default KeyId;\n", "import { KeyId } from \"./KeyId.js\";\nimport { Passphrase, PassphraseEntry } from \"./PassphraseEntry.js\";\nimport * as readline from \"node:readline\";\nimport { Readable, Writable } from \"node:stream\";\n\nexport interface PassphraseReaderOptions {\n input: Readable;\n output: Writable;\n mask: string | false;\n}\n\nfunction isNewLine(chunk: Buffer | string) {\n return (\n (typeof chunk === \"string\" && chunk.endsWith(\"\\n\")) ||\n (chunk instanceof Buffer && chunk.at(chunk.length - 1) === 0x0a)\n );\n}\n\nexport function readPassphrase(\n prompt: string,\n { input, output, mask }: PassphraseReaderOptions,\n): Promise<Passphrase> {\n let masking = false;\n const rl = readline.createInterface({\n input,\n output: new Writable({\n write: (chunk, encoding: BufferEncoding, callback) => {\n if (masking && !isNewLine(chunk)) {\n output.write(\n mask,\n encoding.endsWith(\"buffer\") ? \"utf8\" : encoding,\n callback,\n );\n } else output.write(chunk, encoding, callback);\n },\n }),\n terminal: true,\n });\n\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => {\n rl.close();\n resolve(answer);\n });\n setTimeout(() => (masking = mask !== false), 0); // wait for I/O interrupt\n });\n}\n\nconst prompts: {\n authenticate: Record<string, string>;\n authenticateRetry: Record<string, string>;\n configurePassphrase: Record<string, string>;\n configurePassphraseRetry: Record<string, string>;\n confirmConfigurePassphrase: Record<string, string>;\n} = {\n authenticate: {\n \"\": \"Passphrase for {keyId}: \",\n ko: \"{keyId} \uD0A4\uC758 \uC554\uD638: \",\n qts: \"AUTHENTICATE:{keyId}\", // for unit test\n },\n authenticateRetry: {\n \"\": \"Incorrect; try again: \",\n ko: \"\uD2C0\uB9BC. \uC7AC\uC2DC\uB3C4: \",\n qts: \"AUTHENTICATE_RETRY:{keyId}\", // for unit test\n },\n configurePassphrase: {\n \"\": \"New passphrase: \",\n ko: \"\uC0C8 \uC554\uD638: \",\n qts: \"CONFIGURE_PASSPHRASE\", // for unit test\n },\n configurePassphraseRetry: {\n \"\": \"Mismatch; new passphrase: \",\n ko: \"\uD2C0\uB9BC. \uC0C8 \uC554\uD638 \uC7AC\uC785\uB825:\",\n qts: \"CONFIGURE_PASSPHRASE_RETRY\", // for unit test\n },\n confirmConfigurePassphrase: {\n \"\": \"Confirm passphrase: \",\n ko: \"\uC554\uD638 \uD655\uC778:\",\n qts: \"CONFIRM_CONFIGURE_PASSPHRASE\", // for unit test\n },\n};\n\nfunction getLocale(): string {\n return Intl.DateTimeFormat().resolvedOptions().locale;\n}\n\ninterface TtyPassphraseEntryOptions extends PassphraseReaderOptions {\n locale: string;\n}\n\nexport class TtyPassphraseEntry implements PassphraseEntry {\n #options: TtyPassphraseEntryOptions;\n\n constructor(options: Partial<TtyPassphraseEntryOptions> = {}) {\n this.#options = {\n input: options.input ?? process.stdin,\n output: options.output ?? process.stdout,\n mask: options.mask ?? \"*\",\n locale: options.locale ?? getLocale(),\n };\n }\n\n #getPrompt(promptType: keyof typeof prompts) {\n const table = prompts[promptType];\n let locale = this.#options.locale;\n let msg;\n while (msg == null) {\n msg = table[locale];\n locale = locale.replace(/(^|[-_.])[^-_.]*$/, \"\");\n }\n return msg;\n }\n\n authenticate(keyId: KeyId, firstAttempt: boolean): Promise<Passphrase> {\n const message = this.#getPrompt(\n firstAttempt ? \"authenticate\" : \"authenticateRetry\",\n );\n const prompt = message.replace(/\\{keyId\\}/g, keyId);\n return readPassphrase(prompt, this.#options);\n }\n\n async configurePassphrase(): Promise<Passphrase> {\n let prompt = this.#getPrompt(\"configurePassphrase\");\n const retryPrompt = this.#getPrompt(\"configurePassphraseRetry\");\n const confirmPrompt = this.#getPrompt(\"confirmConfigurePassphrase\");\n while (true) {\n const passphrase = await readPassphrase(prompt, this.#options);\n const confirmPassphrase = await readPassphrase(\n confirmPrompt,\n this.#options,\n );\n if (passphrase === confirmPassphrase) return passphrase;\n prompt = retryPrompt;\n }\n }\n}\n", "import { isKeyId, KeyId } from \"./KeyId.js\";\nimport { Passphrase, PassphraseEntry } from \"./PassphraseEntry.js\";\nimport {\n Address,\n ExportableAccount,\n PublicKey,\n RawPrivateKey,\n Signature,\n} from \"@planetarium/account\";\nimport { crypto } from \"#crypto\";\nimport { pbkdf2Async } from \"@noble/hashes/pbkdf2\";\nimport { scryptAsync } from \"@noble/hashes/scrypt\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { keccak_256 } from \"@noble/hashes/sha3\";\n\nexport type Web3KeyObjectKdf =\n | {\n kdf: \"pbkdf2\";\n kdfparams: {\n c: number;\n dklen: number;\n prf: \"hmac-sha256\";\n salt: string;\n };\n }\n | {\n kdf: \"scrypt\";\n kdfparams: {\n dklen: number;\n n: number;\n p: number;\n r: number;\n salt: string;\n };\n };\n\nexport type Web3KeyObjectCipher = {\n cipher: \"aes-128-ctr\";\n cipherparams: {\n iv: string;\n };\n ciphertext: string;\n mac: string;\n};\n\nexport interface Web3KeyObject {\n version: 3;\n id: KeyId;\n address: string;\n crypto: Web3KeyObjectCipher & Web3KeyObjectKdf;\n}\n\nexport class Web3Account implements ExportableAccount {\n #keyObject: Web3KeyObject;\n #passphraseEntry: PassphraseEntry;\n #options: Partial<Web3AccountOptions>;\n\n constructor(\n keyObject: Web3KeyObject,\n passphraseEntry: PassphraseEntry,\n options: Partial<Web3AccountOptions> = {},\n ) {\n this.#keyObject = keyObject;\n this.#passphraseEntry = passphraseEntry;\n this.#options = options;\n }\n\n async #exportPrivateKey(\n options: Partial<Web3AccountOptions> = {},\n ): Promise<RawPrivateKey> {\n let firstAttempt = true;\n let privateKey: RawPrivateKey;\n while (true) {\n const passphrase = await this.#passphraseEntry.authenticate(\n this.#keyObject.id,\n firstAttempt,\n );\n try {\n const result = await decryptKeyObject(this.#keyObject, passphrase, {\n ...this.#options,\n ...options,\n });\n privateKey = result.privateKey;\n } catch (e) {\n if (e instanceof IncorrectPassphraseError) {\n firstAttempt = false;\n continue;\n }\n throw e;\n }\n break;\n }\n return privateKey;\n }\n\n exportPrivateKey(): Promise<RawPrivateKey> {\n return this.#exportPrivateKey({ allowWeakPrivateKey: true });\n }\n\n getAddress(): Promise<Address> {\n return Promise.resolve(Address.fromHex(this.#keyObject.address, true));\n }\n\n async getPublicKey(): Promise<PublicKey> {\n const key = await this.#exportPrivateKey({ allowWeakPrivateKey: true });\n return await key.getPublicKey();\n }\n\n async sign(message: Uint8Array): Promise<Signature> {\n const key = await this.#exportPrivateKey();\n return await key.sign(message);\n }\n}\n\nfunction toHex(bytes: Uint8Array | ArrayBuffer): string {\n const array = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n let hex = \"\";\n for (let i = 0; i < array.length; i++) {\n hex += array[i].toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n\nexport async function encryptKeyObject(\n keyId: KeyId,\n privateKey: RawPrivateKey,\n passphrase: Passphrase,\n): Promise<Web3KeyObject> {\n if (!isKeyId(keyId)) {\n throw new Error(`Invalid key ID: ${keyId}`);\n }\n\n const salt = new Uint8Array(32);\n crypto.getRandomValues(salt);\n const kdf: Web3KeyObjectKdf = {\n kdf: \"pbkdf2\",\n kdfparams: {\n c: 10240,\n dklen: 32,\n prf: \"hmac-sha256\",\n salt: toHex(salt),\n },\n };\n const derivedKey = await deriveKey(kdf, passphrase);\n const cipher = await encipher({\n derivedKey,\n privateKey: privateKey.toBytes(),\n });\n const address = await Address.deriveFrom(privateKey);\n\n return {\n version: 3,\n id: keyId,\n address: address.toHex(\"lower\"),\n crypto: { ...cipher, ...kdf },\n };\n}\n\nexport function isKeyObject(json: unknown): json is Web3KeyObject {\n if (\n typeof json !== \"object\" ||\n json == null ||\n !(\"version\" in json) ||\n json.version !== 3 ||\n !(\"id\" in json) ||\n typeof json.id !== \"string\" ||\n !isKeyId(json.id) ||\n !(\"address\" in json) ||\n typeof json.address !== \"string\"\n ) {\n return false;\n }\n\n try {\n Address.fromHex(json.address, true);\n } catch (e) {\n return false;\n }\n\n return (\n \"crypto\" in json &&\n typeof json.crypto === \"object\" &&\n isKeyObjectCipher(json.crypto) &&\n isKeyObjectKdf(json.crypto)\n );\n}\n\nfunction isKeyObjectCipher(json: unknown): json is Web3KeyObjectCipher {\n return (\n typeof json === \"object\" &&\n json != null &&\n \"cipher\" in json &&\n json.cipher === \"aes-128-ctr\" &&\n \"cipherparams\" in json &&\n typeof json.cipherparams === \"object\" &&\n json.cipherparams != null &&\n \"iv\" in json.cipherparams &&\n typeof json.cipherparams.iv === \"string\" &&\n \"ciphertext\" in json &&\n typeof json.ciphertext === \"string\" &&\n \"mac\" in json &&\n typeof json.mac === \"string\"\n );\n}\n\nfunction isKeyObjectKdf(json: unknown): json is Web3KeyObjectKdf {\n if (typeof json !== \"object\" || json == null || !(\"kdf\" in json)) {\n return false;\n }\n\n switch (json.kdf) {\n case \"pbkdf2\":\n return (\n \"kdfparams\" in json &&\n typeof json.kdfparams === \"object\" &&\n json.kdfparams != null &&\n \"c\" in json.kdfparams &&\n typeof json.kdfparams.c === \"number\" &&\n \"dklen\" in json.kdfparams &&\n typeof json.kdfparams.dklen === \"number\" &&\n \"prf\" in json.kdfparams &&\n json.kdfparams.prf === \"hmac-sha256\" &&\n \"salt\" in json.kdfparams &&\n typeof json.kdfparams.salt === \"string\"\n );\n\n case \"scrypt\":\n return (\n \"kdfparams\" in json &&\n typeof json.kdfparams === \"object\" &&\n json.kdfparams != null &&\n \"dklen\" in json.kdfparams &&\n typeof json.kdfparams.dklen === \"number\" &&\n \"n\" in json.kdfparams &&\n typeof json.kdfparams.n === \"number\" &&\n \"p\" in json.kdfparams &&\n typeof json.kdfparams.p === \"number\" &&\n \"r\" in json.kdfparams &&\n typeof json.kdfparams.r === \"number\" &&\n \"salt\" in json.kdfparams &&\n typeof json.kdfparams.salt === \"string\"\n );\n\n default:\n return false;\n }\n}\n\nexport interface Web3AccountOptions {\n /**\n * Whether to allow weak private keys (i.e. private keys with leading zeros).\n */\n readonly allowWeakPrivateKey: boolean;\n}\n\nexport class WeakPrivateKeyError extends Error {\n readonly name = \"WeakPrivateKeyError\";\n}\n\nexport async function decryptKeyObject(\n keyObject: Web3KeyObject,\n passphrase: Passphrase,\n options: Partial<Web3AccountOptions> = {},\n): Promise<{ keyId: KeyId; privateKey: RawPrivateKey }> {\n if (keyObject == null) {\n throw new Error(\"Key object is null.\");\n } else if (keyObject.version !== 3) {\n throw new Error(`Unsupported key object version: ${keyObject?.version}`);\n } else if (keyObject.crypto == null) {\n throw new Error(\"Key object does not have crypto field.\");\n }\n\n const keyObjectAddress = Address.fromHex(keyObject.address, true);\n const derivedKey = await deriveKey(keyObject.crypto, passphrase);\n let privateKeyBytes = await decipher(keyObject.crypto, derivedKey);\n if (privateKeyBytes.length < 32) {\n const zeroPadded = new Uint8Array(32);\n zeroPadded.set(privateKeyBytes, 32 - privateKeyBytes.length);\n privateKeyBytes = zeroPadded;\n }\n if (privateKeyBytes.at(0) === 0x00 && !options.allowWeakPrivateKey) {\n throw new WeakPrivateKeyError(\n \"The private key given is too weak; keys of length less than 32 bytes \" +\n \"are disallowed by default. See also \" +\n \"the Web3AccountOptions.allowWeakPrivateKey option.\",\n );\n }\n const privateKey = RawPrivateKey.fromBytes(privateKeyBytes);\n const address = await Address.deriveFrom(privateKey);\n if (!keyObjectAddress.equals(address)) {\n throw new Error(\n `Failed to decrypt the key object; expected account ${keyObjectAddress} but got ${address} instead.`,\n );\n }\n return { keyId: keyObject.id, privateKey };\n}\n\nasync function deriveKey(\n kdf: Web3KeyObjectKdf,\n passphrase: Passphrase,\n): Promise<Uint8Array> {\n if (kdf.kdf === \"pbkdf2\") {\n const { c, dklen, prf, salt } = kdf.kdfparams;\n if (dklen < 16) throw new Error(`Too short dklen: ${dklen}`);\n if (prf !== \"hmac-sha256\") throw new Error(`Unsupported prf: ${prf}`);\n const derivedKey = await pbkdf2Async(\n sha256,\n passphrase,\n Buffer.from(salt, \"hex\"),\n {\n c,\n dkLen: dklen,\n },\n );\n if (derivedKey.length < dklen) {\n throw new Error(`Key too short: ${toHex(derivedKey)}`);\n }\n return derivedKey;\n } else if (kdf.kdf === \"scrypt\") {\n const { dklen, n, p, r, salt } = kdf.kdfparams;\n const derivedKey = await scryptAsync(passphrase, salt, { N: n, r, p, dkLen: dklen});\n if (derivedKey.length < dklen) {\n throw new Error(`Key too short: ${toHex(derivedKey)}`);\n }\n return derivedKey;\n }\n\n throw new Error(`Unsupported kdf: ${kdf[\"kdf\"]}`);\n}\n\nexport class IncorrectPassphraseError extends Error {\n readonly name = \"IncorrectPassphraseError\";\n\n constructor(\n readonly expectedMac: Uint8Array,\n readonly actualMac: Uint8Array,\n ) {\n super(`Expected: ${toHex(expectedMac)}, Actual: ${toHex(actualMac)}`);\n }\n}\n\nasync function encipher({\n derivedKey,\n privateKey,\n}: {\n derivedKey: Uint8Array;\n privateKey: Uint8Array;\n}): Promise<Web3KeyObjectCipher> {\n const iv = new Uint8Array(16);\n crypto.getRandomValues(iv);\n const ciphertext = await crypto.subtle.encrypt(\n {\n name: \"AES-CTR\",\n counter: iv,\n length: 128,\n },\n await crypto.subtle.importKey(\n \"raw\",\n derivedKey.subarray(0, 16),\n { name: \"AES-CTR\" },\n false,\n [\"encrypt\"],\n ),\n privateKey,\n );\n return {\n cipher: \"aes-128-ctr\",\n cipherparams: { iv: toHex(iv) },\n ciphertext: toHex(ciphertext),\n mac: toHex(calculateMac(derivedKey, ciphertext)),\n };\n}\n\nasync function decipher(\n cipher: Web3KeyObjectCipher,\n derivedKey: Uint8Array,\n): Promise<Uint8Array> {\n if (cipher.cipher !== \"aes-128-ctr\") {\n throw new Error(`Unsupported cipher: ${cipher.cipher}`);\n }\n\n const ciphertext = new Uint8Array(Buffer.from(cipher.ciphertext, \"hex\"));\n const mac = calculateMac(derivedKey, ciphertext);\n const expectedMac = new Uint8Array(Buffer.from(cipher.mac, \"hex\"));\n if (!mac.every((v, i) => v === expectedMac[i])) {\n throw new IncorrectPassphraseError(expectedMac, mac);\n }\n const decrypted = await crypto.subtle.decrypt(\n {\n name: \"AES-CTR\",\n counter: new Uint8Array(Buffer.from(cipher.cipherparams.iv, \"hex\")),\n length: 128,\n },\n await crypto.subtle.importKey(\n \"raw\",\n derivedKey.subarray(0, 16),\n { name: \"AES-CTR\" },\n false,\n [\"decrypt\"],\n ),\n ciphertext,\n );\n // FIXME: This is a workaround for a bug in @peculiar/webcrypto.\n return decrypted instanceof Uint8Array\n ? decrypted\n : new Uint8Array(decrypted);\n}\n\nfunction calculateMac(\n derivedKey: Uint8Array,\n ciphertext: Uint8Array | ArrayBuffer,\n): Uint8Array {\n const keySubBytes = 16;\n const ciphertextBytes =\n ciphertext instanceof Uint8Array ? ciphertext : new Uint8Array(ciphertext);\n const seal = new Uint8Array(keySubBytes + ciphertextBytes.length);\n if (derivedKey.length < keySubBytes) {\n throw new Error(\n `Too short derived key (${derivedKey.length} < ${keySubBytes}): ${toHex(\n derivedKey,\n )}`,\n );\n }\n seal.set(derivedKey.subarray(derivedKey.length - keySubBytes));\n seal.set(ciphertextBytes, keySubBytes);\n const mac = keccak_256(seal);\n return mac;\n}\n", "import { generateKeyId, KeyId } from \"./KeyId.js\";\nimport { PassphraseEntry } from \"./PassphraseEntry.js\";\nimport {\n encryptKeyObject,\n isKeyObject,\n type Web3AccountOptions,\n Web3Account,\n Web3KeyObject,\n} from \"./Web3Account.js\";\nimport {\n type AccountDeletion,\n type AccountGeneration,\n type AccountImportation,\n type AccountMetadata,\n type AccountRetrieval,\n Address,\n type ImportableKeyStore,\n RawPrivateKey,\n} from \"@planetarium/account\";\nimport { join, getDefaultWeb3KeyStorePath } from \"#path\";\nexport { getDefaultWeb3KeyStorePath } from \"#path\";\nimport * as fs from \"#fs\";\n\nexport interface Web3KeyStoreOptions {\n path?: string;\n passphraseEntry: PassphraseEntry;\n}\n\nconst pattern =\n /^(?:UTC--([0-9]{4}-[0-9]{2}-[0-9]{2})T([0-9]{2}-[0-9]{2}-[0-9]{2})Z--)?([0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})(?:.json)?$$/i;\nexport function parseKeyFilename(\n name: string,\n): undefined | { keyId: KeyId; createdAt?: Date } {\n const match = pattern.exec(name);\n if (match == null) return undefined;\n return {\n keyId: match[3].toLowerCase(),\n createdAt:\n match[1] != null && match[2] != null\n ? new Date(`${match[1]}T${match[2].replace(/-/g, \":\")}Z`)\n : undefined,\n };\n}\n\nexport interface Web3KeyMetadata {\n address?: Address;\n}\n\nexport class Web3KeyStore\n implements ImportableKeyStore<KeyId, Web3Account, Web3KeyMetadata>\n{\n readonly #passphraseEntry: PassphraseEntry;\n readonly #accountOptions: Partial<Web3AccountOptions>;\n\n readonly path: string;\n\n constructor(options: Web3KeyStoreOptions & Partial<Web3AccountOptions>) {\n this.path = options.path ?? getDefaultWeb3KeyStorePath();\n this.#passphraseEntry = options.passphraseEntry;\n this.#accountOptions = options;\n }\n\n async *#listKeyFiles(): AsyncIterable<string> {\n for await (const name of fs.listFiles(this.path)) {\n yield name;\n }\n }\n\n async #getKeyPath(\n keyId: KeyId,\n ): Promise<{ path: string; keyId: string; createdAt?: Date } | undefined> {\n for await (const name of this.#listKeyFiles()) {\n const parsed = parseKeyFilename(name);\n if (parsed != null && parsed.keyId === keyId) {\n return { ...parsed, path: join(this.path, name) };\n }\n }\n return undefined;\n }\n\n async *list(): AsyncIterable<AccountMetadata<KeyId, Web3KeyMetadata>> {\n for await (const name of this.#listKeyFiles()) {\n const parsed = parseKeyFilename(name);\n if (parsed == null) continue;\n const keyPath = join(this.path, name);\n let json: unknown;\n try {\n json = JSON.parse(await fs.readFile(keyPath, { encoding: \"utf8\" }));\n } catch (_) {\n continue;\n }\n if (!isKeyObject(json)) continue;\n let address: Address;\n try {\n address = Address.fromHex(json.address, true);\n } catch (_) {\n continue;\n }\n const metadata: Web3KeyMetadata = { address };\n yield { ...parsed, metadata };\n }\n }\n\n async get(\n keyId: Readonly<KeyId>,\n ): Promise<AccountRetrieval<KeyId, Web3Account, Web3KeyMetadata>> {\n const keyPath = await this.#getKeyPath(keyId);\n if (keyPath == null) return { result: \"keyNotFound\", keyId };\n let json;\n try {\n json = await fs.readFile(keyPath.path, {\n encoding: \"utf8\",\n });\n } catch (e) {\n if (\n e != null &&\n typeof e === \"object\" &&\n \"code\" in e &&\n e.code === \"ENOENT\"\n ) {\n return { result: \"keyNotFound\", keyId };\n }\n return { result: \"error\", keyId, message: `${e}` };\n }\n const keyObject: unknown = JSON.parse(json);\n if (!isKeyObject(keyObject)) {\n return { result: \"error\", keyId, message: \"Invalid key file\" };\n }\n const account = new Web3Account(\n keyObject,\n this.#passphraseEntry,\n this.#accountOptions,\n );\n return {\n result: \"success\",\n account,\n keyId,\n metadata: { address: await account.getAddress() },\n createdAt: keyPath.createdAt,\n };\n }\n\n async generate(\n metadata?: Partial<Web3KeyMetadata>,\n ): Promise<AccountGeneration<KeyId, Web3Account>> {\n if (metadata?.address != null) {\n return {\n result: \"error\",\n message: \"Address cannot be predetermined before generating key\",\n };\n }\n const privateKey = await RawPrivateKey.generate();\n const result = await this.#import(privateKey, metadata);\n if (result.result === \"success\") {\n return {\n result: \"success\",\n keyId: result.keyId,\n account: new Web3Account(result.keyObject, this.#passphraseEntry),\n };\n }\n return result;\n }\n\n async delete(keyId: Readonly<KeyId>): Promise<AccountDeletion<KeyId>> {\n const keyPath = await this.#getKeyPath(keyId);\n if (keyPath == null) return { result: \"keyNotFound\", keyId };\n try {\n await fs.removeFile(keyPath.path);\n } catch (e) {\n return { result: \"error\", message: `${e}` };\n }\n return { result: \"success\", keyId };\n }\n\n async #import(\n privateKey: RawPrivateKey,\n metadata?: Partial<Web3KeyMetadata>,\n ): Promise<\n | {\n readonly result: \"success\";\n readonly keyId: KeyId;\n readonly keyObject: Web3KeyObject;\n }\n | {\n readonly result: \"error\";\n readonly message?: string;\n }\n > {\n if (\n metadata?.address != null &&\n !metadata.address.equals(await Address.deriveFrom(privateKey))\n ) {\n return {\n result: \"error\",\n message:\n \"Address does not match the private key \" +\n \"(hint: you do not have to specify it manually)\",\n };\n }\n const passphrase = await this.#passphraseEntry.configurePassphrase();\n const keyId = generateKeyId();\n const keyObject = await encryptKeyObject(keyId, privateKey, passphrase);\n try {\n await fs.mkdir(this.path, { recursive: true });\n } catch (e) {\n return { result: \"error\", message: `${e}` };\n }\n const createdAt = new Date();\n const keyPath = join(\n this.path,\n `UTC--${createdAt\n .toISOString()\n .replace(/\\.[0-9]+Z$/, \"Z\")\n .replace(/:/g, \"-\")}--${keyId}`,\n );\n try {\n await fs.writeFile(keyPath, JSON.stringify(keyObject), \"utf8\");\n } catch (e) {\n return { result: \"error\", message: `${e}` };\n }\n return { result: \"success\", keyId, keyObject };\n }\n\n async import(\n privateKey: RawPrivateKey,\n metadata?: Partial<Web3KeyMetadata>,\n ): Promise<AccountImportation<KeyId>> {\n const bytes = await privateKey.toBytes();\n if (bytes.at(0) === 0x00 && !this.#accountOptions.allowWeakPrivateKey) {\n return {\n result: \"error\",\n message:\n \"The private key given is too weak; keys of length less than 32 bytes \" +\n \"are disallowed by default. See also \" +\n \"the Web3AccountOptions.allowWeakPrivateKey option.\",\n };\n }\n\n const result = await this.#import(privateKey, metadata);\n if (result.result === \"success\") {\n return { result: \"success\", keyId: result.keyId };\n }\n return result;\n }\n}\n\nexport default Web3KeyStore;\n", "export { join } from \"node:path\";\n\n/**\n * Determines the default key store path. It depends on the platform:\n *\n * - Linux/macOS: `$HOME/.config/planetarium/keystore`\n * - Windows: `%AppData%\\planetarium\\keystore`\n */\nexport function getDefaultWeb3KeyStorePath(): string {\n const { homedir } = require(\"node:os\");\n const path = require(\"node:path\");\n const baseDir =\n process.platform === \"win32\"\n ? process.env.AppData || path.join(homedir(), \"AppData\", \"Roaming\")\n : process.env.XDG_CONFIG_HOME || path.join(homedir(), \".config\");\n // Note that it's not necessary to explicitly choose one of `path.win32` or\n // `path.posix` here, but it makes unit tests less dependent on mocks:\n return (process.platform === \"win32\" ? path.win32 : path.posix).join(\n baseDir,\n \"planetarium\",\n \"keystore\",\n );\n}\n", "import * as fs from \"node:fs/promises\";\n\nexport async function mkdir(\n path: string,\n options?: { recursive: true },\n): Promise<void> {\n await fs.mkdir(path, options);\n}\n\nexport function readFile(\n path: string,\n options?: { encoding: \"utf8\" },\n): Promise<string> {\n return fs.readFile(path, options) as Promise<string>;\n}\n\nexport function removeFile(path: string): Promise<void> {\n return fs.unlink(path);\n}\n\nexport async function* listFiles(directory: string): AsyncIterable<string> {\n let dir;\n try {\n dir = await fs.opendir(directory);\n } catch (e) {\n if (\n typeof e === \"object\" &&\n e != null &&\n \"code\" in e &&\n e.code === \"ENOENT\"\n ) {\n // In case where there is no directory at all (it's likely the first\n // time to run this operation in a system), it should be considered\n // it's just empty (instead of considering it an exceptional case).\n return;\n }\n throw e;\n }\n for await (const dirEntry of dir) {\n if (!dirEntry.isFile()) continue;\n yield dirEntry.name;\n }\n}\n\nexport function writeFile(\n path: string,\n content: string,\n encoding?: \"utf8\",\n): Promise<void> {\n return fs.writeFile(path, content, encoding);\n}\n"], "mappings": "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", "names": ["import_account", "mkdir", "readFile", "writeFile", "readFile", "mkdir", "writeFile"] }