UNPKG

vexjs-keygen

Version:

General purpose library for private key storage and key management.

216 lines (169 loc) 5.3 kB
/** Public Key (VEX6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV) @typedef {string} pubkey */ /** [Wallet Import Format](https://en.bitcoin.it/wiki/Wallet_import_format) (5JMx76CTUTXxpAbwAqGMMVzSeJaP5UVTT5c2uobcpaMUdLAphSp) @typedef {string} wif */ /** Private key object from vexjs-ecc. @typedef {object} privateKey */ /** Master Private Key. Strong random key used to derive all other key types. Has a 'PW' prefix followed by a valid wif. (`'PW' + wif === 'PW5JMx76CTUTXxpAbwAqGMMVzSeJaP5UVTT5c2uobcpaMUdLAphSp'`) @typedef {string} masterPrivateKey */ /** Cold storage / recovery key. Has authoritiy to do everything including account recovery. @typedef {wif} owner */ /** Spending key. Has the authority to do everything except account recovery. @typedef {wif} active */ /** Master private key or one of its derived private keys. @typedef {masterPrivateKey|wif} parentPrivateKey */ /** Signing Keys and(or) Accounts each having a weight that when matched in the signatures should accumulate to meet or exceed the auth's total threshold. @typedef {object} auth @example required_auth: { threshold: 1, keys: [{ key: 'VEX78Cs5HPKY7HKHrSMnR76uj7yeajPuNwSH1Fsria3sJuufwE3Zd', weight: 1 } ], accounts: [] } */ /** Permissions object from Vex blockchain obtained via get_account. See chain API get_account => account.permissions. @typedef {object} accountPermissions @example const accountPermissions = [{ perm_name: 'active', parent: 'owner', required_auth: { threshold: 1, keys: [{ key: 'VEX78Cs5HPKY7HKHrSMnR76uj7yeajPuNwSH1Fsria3sJuufwE3Zd', weight: 1 } ], accounts: [] } },{ perm_name: 'mypermission', parent: 'active', required_auth: { threshold: 1, keys: [{ key: 'VEX78Cs5HPKY7HKHrSMnR76uj7yeajPuNwSH1Fsria3sJuufwE3Zd', weight: 1 } ], accounts: [] } },{ perm_name: 'owner', parent: '', required_auth: { threshold: 1, keys: [{ key: 'VEX78Cs5HPKY7HKHrSMnR76uj7yeajPuNwSH1Fsria3sJuufwE3Zd', weight: 1 } ], accounts: [] } }] */ /** @see [validate.path(keyPath)](./validate.js) @typedef {string} keyPath @example 'owner', 'active', 'active/mypermission' */ /** An expanded version of a private key, a keypath ('active/mypermission'), and its calculated public key (for performance reasons). @typedef {object} keyPathPrivate @property {wif} wif @property {pubkey} pubkey @property {keyPath} path */ /** Glob matching expressions (`active`, `active/**`, `owner/*`). @see https://www.npmjs.com/package/glob#glob-primer - syntax @see https://www.npmjs.com/package/minimatch - implementation @typedef {string} minimatch */ /** Key derviation path (`owner`, `active/*`, `active/**`, `active/mypermission`) @typedef {minimatch} keyPathMatcher */ /** A URI without the prefixing scheme, host, port. @typedef {string} uriData @example '/producers', '/account_recovery#name=..' */ /** A valid regular expression string. The provided string is modified when it is converted to a RegExp object: - A start of line match is implied (`^` is always added, do not add one) - Unless the uriPath ends with `$`, automatically matches query parameters and fragment (hash tag info). - The RegExp that is created is always case-insensitive to help a non-canonical path match. Uri paths should be canonical. @typedef {string} uriMatcher @example '/(transfer|contracts)', '/bare-uri$' @example function createPathMatcher(path) { // Ensure match starts at the begining const prefix = '^' // If path matcher does not end with $, allow Uri query and fragment const suffix = path.charAt(path.length - 1) === '$' ? '' : '\/?([\?#].*)?$' // Path matches are case in-sensitive return new RegExp(prefix + path + suffix, 'i') } */ /** @typedef {uriMatcher|Array<uriMatcher>} uriMatchers */ /** @typedef {Object<keyPathMatcher, uriMatchers>} uriRule @example { 'owner': '/account_recovery$', // <= $ prevents query or fragment params 'active': ['/transfer', '/contracts'] } */ /** @typedef {Object<uriRule>} uriRules Define rules that say which private keys may exist within given locations of the application. If a rule is not found or does not match, the keystore will remove the key. The UI can prompt the user to obtain the needed key again. For any non-trivial configuration, implementions should create a unit test that will test the actual configuration used in the application (see `./uri-rules.test.js` for a template). Paths imply that active is always derived from owner. So, instead of writing `owner/active/**` the path must be written as `active/**`. @example uriRules = { // Hypothetical examples // Allow owner and all derived keys (including active) 'owner': '/account_recovery', // Allow active key (and any derived child) 'active': '/(transfer|contracts)', // Allow keys derived from active (but not active itself) 'active/**': '/producers', // If user-provided or unaudited content could be loaded in a given // page, make sure the root active key is not around on these pages. 'active/**': '/@[\\w\\.]' } */ "use strict";