\r
#accounts: AccountList\r
#id: Entropy\r
- #locked: boolean = true\r
- #m: Bip39Mnemonic | null\r
- #s: Uint8Array<ArrayBuffer> | null\r
+ #locked: boolean\r
+ #m?: Bip39Mnemonic\r
+ #s?: Uint8Array<ArrayBuffer>\r
\r
get id () { return `libnemo_${this.#id.hex}` }\r
get isLocked () { return this.#locked }\r
get isUnlocked () { return !this.#locked }\r
- get mnemonic () { return this.#m instanceof Bip39Mnemonic ? this.#m.phrase : null }\r
- get seed () { return this.#s == null ? this.#s : bytes.toHex(this.#s) }\r
+ get mnemonic () {\r
+ if (this.#locked || this.#m == null) throw new Error('failed to get mnemonic', { cause: 'wallet locked' })\r
+ return this.#m.phrase\r
+ }\r
+ get seed () {\r
+ if (this.#locked || this.#s == null) throw new Error('failed to get seed', { cause: 'wallet locked' })\r
+ return bytes.toHex(this.#s)\r
+ }\r
\r
constructor (id: Entropy, seed?: Uint8Array<ArrayBuffer>, mnemonic?: Bip39Mnemonic) {\r
if (this.constructor === Wallet) {\r
}\r
this.#accounts = new AccountList()\r
this.#id = id\r
- this.#m = mnemonic ?? null\r
- this.#s = seed ?? null\r
+ this.#locked = false\r
+ this.#m = mnemonic\r
+ this.#s = seed\r
}\r
\r
/**\r
* @returns {AccountList} Object with keys of account indexes and values of the corresponding Accounts\r
*/\r
async accounts (from: number = 0, to: number = from): Promise<AccountList> {\r
- if (this.seed == null) {\r
+ if (this.#locked || this.#s == null) {\r
throw new Error('wallet must be unlocked to derive accounts')\r
}\r
if (from > to) {\r
await this.#accounts[a].destroy()\r
delete this.#accounts[a]\r
}\r
+ this.#m?.destroy()\r
bytes.erase(this.#s)\r
- this.#s = null\r
- this.#m = null\r
+ this.#m = undefined\r
+ this.#s = undefined\r
await SafeWorker.assign<boolean>({\r
store: 'Wallet',\r
method: 'destroy',\r
if (typeof password === 'string') {\r
password = utf8.toBytes(password)\r
}\r
- if (password == null || !(password instanceof Uint8Array)) {\r
- throw new Error('Failed to lock wallet')\r
- }\r
try {\r
+ if (password == null || !(password instanceof Uint8Array)) {\r
+ throw new Error('password must be string or bytes')\r
+ }\r
const serialized = JSON.stringify({\r
- id: this.id,\r
- mnemonic: this.mnemonic,\r
- seed: this.seed\r
+ id: this.#id.hex,\r
+ mnemonic: this.#m?.phrase,\r
+ seed: this.#s == null ? this.#s : bytes.toHex(this.#s)\r
})\r
const encoded = utf8.toBytes(serialized)\r
const success = await SafeWorker.assign({\r
if (!success) {\r
throw null\r
}\r
+ this.#m?.destroy()\r
+ bytes.erase(this.#s)\r
+ this.#m = undefined\r
+ this.#s = undefined\r
+ this.#locked = true\r
+ return this.#locked\r
} catch (err) {\r
- throw new Error('Failed to lock wallet')\r
+ throw new Error('failed to lock wallet', { cause: err })\r
} finally {\r
bytes.erase(password)\r
}\r
- bytes.erase(this.#s)\r
- this.#s = null\r
- this.#m = null\r
- this.#locked = true\r
- return true\r
}\r
\r
/**\r
if (typeof password === 'string') {\r
password = utf8.toBytes(password)\r
}\r
- if (password == null || !(password instanceof Uint8Array)) {\r
- throw new Error('Failed to unlock wallet')\r
- }\r
+ let decoded, deserialized, id, mnemonic, seed\r
try {\r
+ if (password == null || !(password instanceof Uint8Array)) {\r
+ throw new Error('password must be string or bytes')\r
+ }\r
const response = await SafeWorker.assign<ArrayBuffer>({\r
method: 'fetch',\r
name: this.id,\r
store: 'Wallet',\r
password: password.buffer\r
})\r
- const decoded = bytes.toUtf8(new Uint8Array(response[this.id]))\r
- const deserialized = JSON.parse(decoded)\r
- let { id, mnemonic, seed } = deserialized\r
+ decoded = bytes.toUtf8(new Uint8Array(response[this.id]))\r
+ deserialized = JSON.parse(decoded)\r
+ id = deserialized.id\r
+ mnemonic = deserialized.mnemonic\r
+ seed = deserialized.seed\r
if (id == null) {\r
throw new Error('ID is null')\r
}\r
this.#s = hex.toBytes(seed)\r
seed = null\r
}\r
+ this.#locked = false\r
+ return true\r
} catch (err) {\r
- throw new Error('Failed to unlock wallet', { cause: err })\r
+ throw new Error('failed to unlock wallet', { cause: err })\r
} finally {\r
bytes.erase(password)\r
+ decoded = deserialized = id = mnemonic = seed = undefined\r
}\r
- this.#locked = false\r
- return true\r
}\r
\r
/**\r