Release 1.0.0 (#94)

* Add some types
* Add prepublish script
* Ignore linting certain files
  * In the future we should add types and re-enable linting
* Use export = syntax
* Allow consumers to use `import keypairs from 'ripple-keypairs'`
  * See: https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require
This commit is contained in:
Elliot Lee
2020-02-05 16:34:53 -08:00
parent 4d0c280996
commit 01e94ad4d6
8 changed files with 89 additions and 70 deletions

View File

@@ -1,9 +1,13 @@
# ripple-keypairs Release History
## 1.0.0-beta.1 (2020-01-28)
## 1.0.0 (2020-02-05)
* Refactor and use TypeScript
* Use Travis CI (.travis.yml)
* Use "dist/*" for distribution files
* Add yarn.lock
* Export members and add default export
* Internal
* Travis: remove node 6 and add node 13 (#59)
* Use published ripple-address-codec (#58)
* Replace TSLint with ESLint + Prettier (#71)
* Add type (#74)
@@ -14,14 +18,6 @@
* Update dependencies
* @types/node, eslint, bn.js, typescript, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, mocha, istanbul, hash.js
## 1.0.0-beta.0 (2019-10-17)
* Refactor and use TypeScript
* Vendor ripple-address-codec (move dependency into this project)
* Add support for Travis CI (.travis.yml)
* Use "dist/*" for distribution files
* Add yarn.lock
## 0.11.0 (2018-10-23)
* Upgrade elliptic (#28)

View File

@@ -1,6 +1,6 @@
{
"name": "ripple-keypairs",
"version": "1.0.0-beta.2",
"version": "1.0.0",
"description": "Cryptographic key pairs for the XRP Ledger",
"files": [
"dist/*"
@@ -18,7 +18,7 @@
},
"devDependencies": {
"@types/mocha": "^7.0.1",
"@types/node": "^13.1.5",
"@types/node": "^13.5.2",
"@typescript-eslint/eslint-plugin": "^2.16.0",
"@typescript-eslint/parser": "^2.16.0",
"codecov": "^3.6.2",
@@ -39,8 +39,9 @@
"scripts": {
"compile": "tsc",
"test": "tsc && nyc mocha",
"coverage": "nyc --reporter=lcov mocha && codecov",
"lint": "eslint . --ext .ts --fix"
"lint": "eslint . --ext .ts --fix",
"prepublish": "yarn lint && yarn test",
"coverage": "nyc --reporter=lcov mocha && codecov"
},
"repository": {
"type": "git",

View File

@@ -16,16 +16,16 @@ const { bytesToHex } = utils
function generateSeed(
options: {
entropy?: Uint8Array
algorithm?: 'ed25519' | 'secp256k1'
algorithm?: 'ed25519' | 'ecdsa-secp256k1'
} = {},
) {
): string {
assert(!options.entropy || options.entropy.length >= 16, 'entropy too short')
const entropy = options.entropy ? options.entropy.slice(0, 16) : brorand(16)
const type = options.algorithm === 'ed25519' ? 'ed25519' : 'secp256k1'
return addressCodec.encodeSeed(entropy, type)
}
function hash(message) {
function hash(message): number[] {
return hashjs
.sha512()
.update(message)
@@ -34,7 +34,13 @@ function hash(message) {
}
const secp256k1 = {
deriveKeypair(entropy, options) {
deriveKeypair(
entropy: Uint8Array,
options?: object,
): {
privateKey: string
publicKey: string
} {
const prefix = '00'
const privateKey =
@@ -51,7 +57,7 @@ const secp256k1 = {
return { privateKey, publicKey }
},
sign(message, privateKey) {
sign(message, privateKey): string {
return bytesToHex(
Secp256k1.sign(hash(message), hexToBytes(privateKey), {
canonical: true,
@@ -59,13 +65,18 @@ const secp256k1 = {
)
},
verify(message, signature, publicKey) {
verify(message, signature, publicKey): boolean {
return Secp256k1.verify(hash(message), signature, hexToBytes(publicKey))
},
}
const ed25519 = {
deriveKeypair(entropy) {
deriveKeypair(
entropy: Uint8Array,
): {
privateKey: string
publicKey: string
} {
const prefix = 'ED'
const rawPrivateKey = hash(entropy)
const privateKey = prefix + bytesToHex(rawPrivateKey)
@@ -74,7 +85,7 @@ const ed25519 = {
return { privateKey, publicKey }
},
sign(message, privateKey) {
sign(message, privateKey): string {
// caution: Ed25519.sign interprets all strings as hex, stripping
// any non-hex characters without warning
assert(Array.isArray(message), 'message must be array of octets')
@@ -83,7 +94,7 @@ const ed25519 = {
)
},
verify(message, signature, publicKey) {
verify(message, signature, publicKey): boolean {
return Ed25519.verify(
message,
hexToBytes(signature),
@@ -92,12 +103,19 @@ const ed25519 = {
},
}
function select(algorithm) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function select(algorithm): any {
const methods = { 'ecdsa-secp256k1': secp256k1, ed25519 }
return methods[algorithm]
}
function deriveKeypair(seed, options) {
function deriveKeypair(
seed: string,
options?: object,
): {
publicKey: string
privateKey: string
} {
const decoded = addressCodec.decodeSeed(seed)
const algorithm = decoded.type === 'ed25519' ? 'ed25519' : 'ecdsa-secp256k1'
const method = select(algorithm)
@@ -111,34 +129,34 @@ function deriveKeypair(seed, options) {
return keypair
}
function getAlgorithmFromKey(key) {
function getAlgorithmFromKey(key): 'ed25519' | 'ecdsa-secp256k1' {
const bytes = hexToBytes(key)
return bytes.length === 33 && bytes[0] === 0xed
? 'ed25519'
: 'ecdsa-secp256k1'
}
function sign(messageHex, privateKey) {
function sign(messageHex, privateKey): string {
const algorithm = getAlgorithmFromKey(privateKey)
return select(algorithm).sign(hexToBytes(messageHex), privateKey)
}
function verify(messageHex, signature, publicKey) {
function verify(messageHex, signature, publicKey): boolean {
const algorithm = getAlgorithmFromKey(publicKey)
return select(algorithm).verify(hexToBytes(messageHex), signature, publicKey)
}
function deriveAddressFromBytes(publicKeyBytes: Buffer) {
function deriveAddressFromBytes(publicKeyBytes: Buffer): string {
return addressCodec.encodeAccountID(
utils.computePublicKeyHash(publicKeyBytes),
)
}
function deriveAddress(publicKey) {
return deriveAddressFromBytes(hexToBytes(publicKey))
function deriveAddress(publicKey): string {
return deriveAddressFromBytes(Buffer.from(hexToBytes(publicKey)))
}
function deriveNodeAddress(publicKey) {
function deriveNodeAddress(publicKey): string {
const generatorBytes = addressCodec.decodeNodePublic(publicKey)
const accountPublicBytes = accountPublicFromPublicGenerator(generatorBytes)
return deriveAddressFromBytes(accountPublicBytes)
@@ -146,7 +164,7 @@ function deriveNodeAddress(publicKey) {
const { decodeSeed } = addressCodec
module.exports = {
export = {
generateSeed,
deriveKeypair,
sign,

View File

@@ -1,3 +1,5 @@
/* eslint-disable */
import * as elliptic from 'elliptic'
import Sha512 from './sha512'

View File

@@ -1,3 +1,5 @@
/* eslint-disable */
import * as hashjs from 'hash.js'
import * as BigNum from 'bn.js'

View File

@@ -2,7 +2,7 @@ import * as assert from 'assert'
import * as hashjs from 'hash.js'
import * as BN from 'bn.js'
function bytesToHex(a) {
function bytesToHex(a): string {
return a
.map((byteValue) => {
const hex = byteValue.toString(16).toUpperCase()
@@ -11,7 +11,7 @@ function bytesToHex(a) {
.join('')
}
function hexToBytes(a) {
function hexToBytes(a): number[] {
assert(a.length % 2 === 0)
return new BN(a, 16).toArray(null, a.length / 2)
}

View File

@@ -1,8 +1,8 @@
{
"compilerOptions": {
// Basic Options
"target": "ES6",
"module": "commonjs",
"target": "ES2017",
"module": "CommonJS",
"declaration": true,
"declarationMap": true,
"sourceMap": true,

View File

@@ -10,16 +10,16 @@
"@babel/highlight" "^7.8.3"
"@babel/core@^7.7.5":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.3.tgz#30b0ebb4dd1585de6923a0b4d179e0b9f5d82941"
integrity sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e"
integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==
dependencies:
"@babel/code-frame" "^7.8.3"
"@babel/generator" "^7.8.3"
"@babel/helpers" "^7.8.3"
"@babel/parser" "^7.8.3"
"@babel/generator" "^7.8.4"
"@babel/helpers" "^7.8.4"
"@babel/parser" "^7.8.4"
"@babel/template" "^7.8.3"
"@babel/traverse" "^7.8.3"
"@babel/traverse" "^7.8.4"
"@babel/types" "^7.8.3"
convert-source-map "^1.7.0"
debug "^4.1.0"
@@ -30,10 +30,10 @@
semver "^5.4.1"
source-map "^0.5.0"
"@babel/generator@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.3.tgz#0e22c005b0a94c1c74eafe19ef78ce53a4d45c03"
integrity sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==
"@babel/generator@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e"
integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==
dependencies:
"@babel/types" "^7.8.3"
jsesc "^2.5.1"
@@ -63,13 +63,13 @@
dependencies:
"@babel/types" "^7.8.3"
"@babel/helpers@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.3.tgz#382fbb0382ce7c4ce905945ab9641d688336ce85"
integrity sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==
"@babel/helpers@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73"
integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==
dependencies:
"@babel/template" "^7.8.3"
"@babel/traverse" "^7.8.3"
"@babel/traverse" "^7.8.4"
"@babel/types" "^7.8.3"
"@babel/highlight@^7.8.3":
@@ -81,10 +81,10 @@
esutils "^2.0.2"
js-tokens "^4.0.0"
"@babel/parser@^7.7.5", "@babel/parser@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.3.tgz#790874091d2001c9be6ec426c2eed47bc7679081"
integrity sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==
"@babel/parser@^7.7.5", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8"
integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==
"@babel/template@^7.7.4", "@babel/template@^7.8.3":
version "7.8.3"
@@ -95,16 +95,16 @@
"@babel/parser" "^7.8.3"
"@babel/types" "^7.8.3"
"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.3.tgz#a826215b011c9b4f73f3a893afbc05151358bf9a"
integrity sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==
"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c"
integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==
dependencies:
"@babel/code-frame" "^7.8.3"
"@babel/generator" "^7.8.3"
"@babel/generator" "^7.8.4"
"@babel/helper-function-name" "^7.8.3"
"@babel/helper-split-export-declaration" "^7.8.3"
"@babel/parser" "^7.8.3"
"@babel/parser" "^7.8.4"
"@babel/types" "^7.8.3"
debug "^4.1.0"
globals "^11.1.0"
@@ -154,7 +154,7 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.1.tgz#5d7ec2a789a1f77c59b7ad071b9d50bf1abbfc9e"
integrity sha512-L/Nw/2e5KUaprNJoRA33oly+M8X8n0K+FwLTbYqwTcR14wdPWeRkigBLfSFpN/Asf9ENZTMZwLxjtjeYucAA4Q==
"@types/node@^13.1.5":
"@types/node@^13.5.2":
version "13.7.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.0.tgz#b417deda18cf8400f278733499ad5547ed1abec4"
integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==
@@ -1378,9 +1378,9 @@ istanbul-lib-hook@^3.0.0:
append-transform "^2.0.0"
istanbul-lib-instrument@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz#53321a7970f076262fd3292c8f9b2e4ac544aae1"
integrity sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==
version "4.0.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6"
integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==
dependencies:
"@babel/core" "^7.7.5"
"@babel/parser" "^7.7.5"
@@ -2028,9 +2028,9 @@ resolve-from@^5.0.0:
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2:
version "1.15.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5"
integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==
version "1.15.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
dependencies:
path-parse "^1.0.6"