Keystore
- class Keystore()
A Keystore holds an encrypted key pair (an Address and its private key) and is the preferred way to pass addresses and private keys through DCP APIs. Keystores are stored on disk as passphrase-protected Keystore Files, and are the objects returned by
wallet.get()/load().Keystore is an
EventEmitter; see Events below for the events it emits.IdKeystore,AuthKeystore, andBankAccountKeystoreare subclasses of Keystore used to represent different kinds of addresses – see Subclasses below. They share this exact constructor and method set.
Constructor
The constructor is async, and always returns a Promise which resolves with a locked Keystore whose address is known. Any form may trigger exports.passphrasePrompt to solicit a passphrase from the user.
Form 1
new Keystore();
Generates a random private key and prompts the user for a passphrase to encrypt it with.
Form 2
new Keystore(privateKey);
Arguments:
privateKey (string|object) - A private key, in hex string format or anything else accepted by the
PrivateKeyconstructor.
Uses the given private key, prompting the user for a passphrase to encrypt it with.
Form 3
new Keystore(privateKey, passphrase);
Arguments:
privateKey (string|object) - As in Form 2.
passphrase (string|false) - Passphrase to encrypt the private key with. Pass
falseto use the empty passphrase.
Uses the given private key, encrypted with the given passphrase.
Form 4
new Keystore(foreignKeystoreObject, passphrase);
Arguments:
foreignKeystoreObject (object) - A keystore object from a third party, such as MyEtherWallet, geth, or Web3.
passphrase (string) - Optional. If omitted, the empty passphrase is tried first, then the user is prompted.
Parses a third-party keystore object. Rejects with an Error if the object can’t be parsed. toJSON() on the resulting Keystore returns the original object, stringified.
Form 5
new Keystore(jsonString, passphrase);
Identical to Form 4, except jsonString is a JSON-encoded string (parsed with JSON.parse() before proceeding as in Form 4). toJSON() on the resulting Keystore returns the original string, unaltered.
Form 6
new Keystore(keystoreObject);
Arguments:
keystoreObject (Keystore) - An existing Keystore object.
Copies another Keystore. The new object shares the same encrypted secret as keystoreObject, so it unlocks with the same passphrase.
Form 7
new Keystore(null, passphrase);
Arguments:
passphrase (string) - The passphrase used to encrypt the newly generated private key.
Generates a random private key, encrypted with the given passphrase (no prompt).
Note
Forms 2-5’s argument descriptions above intentionally depart slightly from this class’s own source comments, which describe Forms 2 and 3 as also accepting “an Ethereum v3 Keystore object” – that phrasing appears to be copied in error from Forms 4/5 and doesn’t match the constructor’s actual branching logic (checked against dcpEth.PrivateKey(arguments[0], true)), which only accepts private-key-like values there.
Properties
address
- Keystore.address
- Type:
Address
The (public) address represented by this Keystore.
label
Methods
toJSON
- toJSON()
Serializes the Keystore to a plain object suitable for writing to a Keystore File or sending to a third party, without leaking the decrypted private key.
- Return type:
object
Note
The returned object also carries two properties not present in the originally-imported/generated keystore data: timestamp (the result of String(new Date()) at serialization time) and process (the invoking process’s name on Node.js, or the calling script/page’s origin+pathname in a browser). These are added fresh on every call to toJSON(), so two serializations of the same Keystore moments apart will differ in these two fields even though the encrypted secret is identical.
unlock
- unlock(passphrase, lockTimerDuration, autoReset)
Unlocks the Keystore for a given amount of time so that
getPrivateKey()and related operations don’t need to ask for a passphrase. This is an async method that returns a Promise.- Arguments:
passphrase (string) – Optional. If omitted, exports.passphrasePrompt is invoked to solicit it from the user, unless the keystore is already unlocked.
lockTimerDuration (number) – Number of seconds to stay unlocked for. If omitted, the keystore re-locks immediately after the next call to
getPrivateKey().autoReset (boolean) – When true, a subsequent call to
getPrivateKey()resets and restarts the unlock timer.
- Throws:
An error with code DCP_WA:UNLOCKX if the keystore could not be unlocked (e.g. wrong passphrase).
While the unlock timer is running, calling unlock again to extend it requires a passphrase check; if the new duration is longer than one previously set with autoReset, the autoReset duration itself is increased so future calls to getPrivateKey keep resetting to at least that length.
lock
- lock()
Locks the Keystore immediately, discarding the decrypted private key from memory.
isLocked
- isLocked()
- Return type:
boolean
isUnlocked
- isUnlocked()
- Return type:
boolean
getPrivateKey
- getPrivateKey()
Returns the decrypted private key, unlocking the Keystore (prompting for a passphrase if necessary) as needed. This is an async method that returns a Promise.
- Return type:
PrivateKey
Note
If you find yourself reaching for this, consider whether makeSignedMessage(), makeSignedMessageObject(), or makeSignature() already do what you need without handling the raw key yourself.
testPassphrase
- testPassphrase(passphrase)
Checks whether a passphrase unlocks this Keystore’s private key, without actually unlocking it. This is an async method that returns a Promise.
- Arguments:
passphrase (string) – The passphrase to test.
- Return type:
boolean
makeSignedMessage
- makeSignedMessage(messageBody)
Signs messageBody with this Keystore’s private key, implementing Connection.Message.sign (see the Protocol API). This is an async method that returns a Promise.
- Arguments:
messageBody (object) – The message to sign.
- Return type:
Promise<string>
makeSignedMessageObject
- makeSignedMessageObject(messageBody)
Like
makeSignedMessage(), but returns the object { owner, signature, body } instead of a string. This is an async method that returns a Promise.- Arguments:
messageBody (object) – The message to sign.
- Return type:
Promise<object>
makeSignedLightWeightMessageObject
- makeSignedLightWeightMessageObject(messageLightWeight, messageBody)
Like
makeSignedMessageObject(), except the signature is computed only over messageLightWeight, so large messageBody payloads don’t need to be hashed in full. Returns { owner, signature, auth: messageLightWeight, body }. This is an async method that returns a Promise.- Arguments:
messageLightWeight (object) – The (small) portion of the message to actually sign.
messageBody (object) – The full message body to attach, unsigned.
- Return type:
Promise<object>
makeSignature
- makeSignature(messageBody)
Creates a raw signature for messageBody, implementing Connection.Request.authorize (see the Protocol API). This is an async method that returns a Promise.
- Arguments:
messageBody (object) – The message to sign. Non-string values are serialized with JSON.stringify() first.
- Return type:
Promise<object>
Note
Passing undefined throws synchronously ('tried to make a signature for undefined') rather than signing the string "undefined".
Events
Keystore is an EventEmitter. Handlers are attached the usual way, for example, keystore.on('lock', () => { ... }).
lock - emitted immediately after the Keystore becomes locked, whether via an explicit call to
lock()or because an unlock timer expired.unlock - emitted immediately after the Keystore successfully unlocks.
Subclasses
IdKeystore, AuthKeystore, and BankAccountKeystore all extend Keystore with the exact same constructor forms and methods described above – they exist to label why a given Keystore is being used, not to change its behaviour.
IdKeystore - Represents an identity, such as the Scheduler, the Portal, or an end user. Messages signed with an identity’s private key carry the same access privileges as that user’s Portal login.
AuthKeystore - Represents authorization granted to a third party (for example, to withdraw or escrow funds up to some limit).
wallet.get()andload()returnAuthKeystoreobjects.BankAccountKeystore - Represents a bank account directly. Knowing the private key is sufficient to withdraw or escrow funds from the account.
Example
const wallet = require('dcp/wallet');
// Create a brand new keystore, encrypted with an explicit passphrase (Form 3),
// and write it out as a Keystore File.
const ks = await new wallet.Keystore(null, 'correct horse battery staple');
require('fs').writeFileSync('./my.keystore', JSON.stringify(ks));
// ... later, or in a different process ...
// Load it back, unlock it, and sign a message with it.
const { keystore } = await wallet.load('./my.keystore');
await keystore.unlock('correct horse battery staple');
const signedMessage = await keystore.makeSignedMessage({ hello: 'world' });