The Keystore API is a library for working with DCP, the Distributed Compute Protocol, to perform operations related to Addresses, Keystores, and Wallets.
Date | Author | Change |
---|---|---|
May 24 2019 | Wes Garland | Added DataTypes |
May 23 2019 | Wes Garland | Initial Revision |
This document is intended for both the KDS DCP dev team and external developers writing DCP applications.
A unique identifier in DCP which can be used as a Bank Account identifier (account number), Address on the Ethereum network, or as an identifier for any other arbitrary entity (eg. a user, the bank, an administrator, etc.).
A data structure which stores a (public) Address and a private key. The Wallet is used by one party to sign transactions over DCP in a way which allows the other party to know (within cryptographic certainty) that the first party has the private key, and hence is authorized to move funds associated with the Address.
A data structure which stores an encrypted wallet. Generally speaking, the Wallet will be encrypted with a passphrase. It is possible to encrypt a Wallet with no passphrase.
A file which stores a JSON-encoded Keystore. This is the preferred method to private keys.
DCP Addresses can be used as a Bank Account identifier (account number), an Address on the Ethereum network, or as an identifier for any other arbitrary entity (eg. a user, the bank, an administrator, etc.).
With the notable exception of Bank Accounts and Ethereum block chain requests using the same Address, it is considered very bad practice use the same Address to identify multiple entities. It is important to remember that
Addresses may be used to identify access realms; conceptually, we simply tie the access realm to the Bank Account (whether it really exists or not). For example, we might nominate a particular Address to represent “scheduler maintenance functions”, and require messages which are signed with the private key corresponding to the Address in order to access these functions.
Addresses are represented by Strings which contain 20-byte hexadecimal numbers (no prefix). All comparisons between Addresses must be case-insensitive. An Address must never be programmatically altered, as the alteration could damage the case-encoded checksum, which will be used by future versions of the Keystore API.
Keystores are stored in Keystore objects. These objects are instanceof require('keystore').Keystore
. There is currently no guarantee that the Keystore objects’ constructor is also require('keystore').Keystore
.
Wallets are stored in Wallet objects. These objects are instanceof require('keystore').Wallet
. There is currently no guarantee that the Keystore objects’ constructor is also require('keystore').Wallet
.
keystore.passphrasePrompt(string)
This function accepts a string, which is displayed to the user, and returns a string which was entered by the user.
In NodeJS applications, this function solicits input from the standard input, and does not display what the user is typing.
In browser applications, this function solicits input from the active browser window, using an <INPUT type="password">
element.
The keystore
module will always use its passphrasePrompt
export internally when it needs a passphrase, for example, to unlock a Keystore object. This means that developers can monkey-patch the module as necessary to produce a user experience which is consistent with their application.
Keystore Files are loaded, by default, from the .dcp
directory in the user’s home directory. They are stored in files ending in .keystore
. The first part of the filename corresponds, by default, to the name assigned to the Keystore in the DCP Web Portal.
Keystore Files can be either files on the user’s local filesystem, browser local storage, or within the Distributed Computer’s Wallet Manager.
The next version of this specification will allow NodeJS Platforms to use the Distributed Computer’s Wallet Manager.
Unified and Web Platform implementation are currently out-of-scope – wait for later version of spec
This function accepts a Wallet name or filename, reads the contents of the associated file, and returns an object, which has the following properties:
keystore - an object corresponding to the Keystore that was loaded
safe - a boolean flag which, when true, indicates that the keystore was read from a secure location.
keystore.loadSync(filename)
- NodeJS onlyfilename
must begin with path.sep
, '.' + path.sep
, or '..' + path.sep
.
The safe flag is set to true to indicate that the Keystore file was stored safely; this happens if and only if the following conditions are true:
keystore.loadSync(name, options)
This form creates a Keystore File filename based on its arguments, performing the operations described in form 1 once the filename has been determined.
name
must not begin with path.sep
, '.' + path.sep
, nor '..' + path.sep
. If a user creates a Wallet that happens to be named like this, they will either need to rename the file, or specify the full pathname, invoking form 1
The options
object can be used to override the default filename and directory for the Keystore File.
option | behaviour |
---|---|
name | override the default Wallet name, normally “default” |
dir | override default Wallet directory, normally the “.dcp” directory in the home directory belonging to the user invoking the program (NodeJS only) |
This function accepts a Keystore object and returns a Wallet object. If it cannot return a Wallet object, it will throw an Error.
keystore.unlock(keystore)
keystore.passphasePrompt
.keystore.unlock(keystore, options)
This function examines parameters and accepts options relating to its environment, uses this information to select a Keystore file, load it via keystore.loadSync
, and return a Wallet object. If it cannot return a Wallet object, this function will throw an Error.
keystore.getWallet(options)
This form loads a Keystore form a Keystore File via keystore.loadSync
and returns a Wallet object. The options
object is used to override default parameters which help to identify and locate the Keystore file.
option | behaviour |
---|---|
name | override the default Wallet name, normally “default” |
dir | override default Wallet directory, normally the “.dcp” directory in the home directory belonging to the user invoking the program (NodeJS only) |
checkEmpty | When specified (is an ownProperty), this value is passed as the checkEmpty option value when keystore.unlock is invoked. |
Tip: the options objects for getWallet(), loadSync(), and unlock() are compatible.
The Wallet will be extracted using the keystore.unlock
function. If loadSync
does not indicate that the Wallet was stored safely, the empty passphrase will not be tried during the call to unlock
. This behaviour is to ensure that end users do not accidentally leave Keystore Files with empty passphrases lying around in their filesystems with world-readable permissions.
keystore.getWallet()
This form is equivalent to keystore.getWallet({})
.
keystore.getWallet(string)
This form is equivalent to keystore.getWallet({name: string})
keystore.getWallet(array)
This form accepts an Array-like object, formatted like process.argv
, to specify options for invoking form 1. Its purpose is to unify Keystore, Wallet, and Address-related options for programs written in NodeJS.
argument | behaviour |
---|---|
–private-key | Generate a wallet corresponding to the specified private key, ignoring all other considerations |
-i name | Override the name option |
-p | Set the checkEmpty option to false |
keystore.getWallet(array, options)
This form accepts an Array-like object, as described in form 4, and an options object as described in form 1. Its behaviour is to generate an options object from the array, merge the passed options object into this options object, and invoke form 1.
To be clear, the options
argument has a higher precedence than the array
argument.
keystore.getWallet(array, string)
This form is equivalent to keystore.getWallet(array, {name: string})
This function generates Wallet objects.
keystore.generateWallet()
keystore.generateWallet(privateKey)