From 69dc50dfdcd4fe9fe07775bb29a03e44d87794cf Mon Sep 17 00:00:00 2001 From: Jonathan Underwood Date: Fri, 17 May 2019 11:59:33 +0900 Subject: [PATCH] Fix TS (#15) * Fix TS stuff * single quote + trailing commas for tests folder * Specific for includes... allow for ts testing later * Export Invoice and Rate interfaces to library user * Use prepare * test checks format and lint --- package-lock.json | 85 +++++++++++++++++++++++++++++++++++++--- package.json | 30 +++++++++----- src/core/client.ts | 49 ++++++++++++----------- src/core/cryptography.ts | 10 ++--- src/index.ts | 2 + src/models/invoice.ts | 69 +++++++++++++++++++++++++++++++- src/models/rate.ts | 6 ++- tests/sample.js | 4 +- tests/sample.ts | 2 +- tsconfig.json | 25 ++++++++---- tslint.json | 6 --- 11 files changed, 227 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index 685b332..07907ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/base-x/-/base-x-3.0.0.tgz", "integrity": "sha512-vnqSlpsv9uFX5/z8GyKWAfWHhLGJDBkrgRRsnxlsX23DHOlNyqP/eHQiv4TwnYcZULzQIxaWA/xRWU9Dyy4qzw==", + "dev": true, "requires": { "@types/node": "*" } @@ -35,12 +36,14 @@ "@types/bluebird": { "version": "3.5.26", "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.26.tgz", - "integrity": "sha512-aj2mrBLn5ky0GmAg6IPXrQjnN0iB/ulozuJ+oZdrHRAzRbXjGmu4UXsNCjFvPbSaaPZmniocdOzsM392qLOlmQ==" + "integrity": "sha512-aj2mrBLn5ky0GmAg6IPXrQjnN0iB/ulozuJ+oZdrHRAzRbXjGmu4UXsNCjFvPbSaaPZmniocdOzsM392qLOlmQ==", + "dev": true }, "@types/bn.js": { "version": "4.11.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", "integrity": "sha512-AEAZcIZga0JgVMHNtl1CprA/hXX7/wPt79AgR4XqaDt7jyj3QWYw6LPoOiznPtugDmlubUnAahMs2PFxGcQrng==", + "dev": true, "requires": { "@types/node": "*" } @@ -49,6 +52,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/bs58/-/bs58-4.0.0.tgz", "integrity": "sha512-gYX+MHD4G/R+YGYwdhG5gbJj4LsEQGr3Vg6gVDAbe7xC5Bn8dNNG2Lpo6uDX/rT5dE7VBj0rGEFuV8L0AEx4Rg==", + "dev": true, "requires": { "@types/base-x": "*" } @@ -56,12 +60,14 @@ "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", + "dev": true }, "@types/elliptic": { "version": "6.4.6", "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.6.tgz", "integrity": "sha512-rAQEVgU0P+VWWTjUw3yGlVeDezyObfjfWq1d1noDOKB1VldM1u6Uvz4Va6eGkWUSDRFfDCOQmiRvqHRO8EvZGg==", + "dev": true, "requires": { "@types/bn.js": "*" } @@ -70,6 +76,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "dev": true, "requires": { "@types/node": "*" } @@ -77,12 +84,14 @@ "@types/node": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.5.tgz", - "integrity": "sha512-/OMMBnjVtDuwX1tg2pkYVSqRIDSmNTnvVvmvP/2xiMAAWf4a5+JozrApCrO4WCAILmXVxfNoQ3E+0HJbNpFVGg==" + "integrity": "sha512-/OMMBnjVtDuwX1tg2pkYVSqRIDSmNTnvVvmvP/2xiMAAWf4a5+JozrApCrO4WCAILmXVxfNoQ3E+0HJbNpFVGg==", + "dev": true }, "@types/request": { "version": "2.48.1", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", + "dev": true, "requires": { "@types/caseless": "*", "@types/form-data": "*", @@ -94,6 +103,7 @@ "version": "4.1.42", "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.42.tgz", "integrity": "sha512-b8li55sEZ00BXZstZ3d8WOi48dnapTqB1VufEG9Qox0nVI2JVnTVT1Mw4JbBa1j+1sGVX/qJ0R4WDv4v2GjT0w==", + "dev": true, "requires": { "@types/bluebird": "*", "@types/request": "*" @@ -102,12 +112,14 @@ "@types/tough-cookie": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", - "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" + "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==", + "dev": true }, "@types/underscore": { "version": "1.8.14", "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.14.tgz", - "integrity": "sha512-xbzi6UaATVKupInG3D65/EPQ3qkJCvG2ZAzmlIYt6x93ACOEX2Y0fHW4/e8TF3G7q5KB2l7wTZgzfNjyYDMuZw==" + "integrity": "sha512-xbzi6UaATVKupInG3D65/EPQ3qkJCvG2ZAzmlIYt6x93ACOEX2Y0fHW4/e8TF3G7q5KB2l7wTZgzfNjyYDMuZw==", + "dev": true }, "acorn": { "version": "6.1.1", @@ -263,6 +275,12 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -334,6 +352,12 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1084,6 +1108,12 @@ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -1095,6 +1125,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.1.tgz", + "integrity": "sha512-TzGRNvuUSmPgwivDqkZ9tM/qTGW9hqDKWOE9YHiyQdixlKbv7kvEqsmDPrcHJTKwthU774TQwZXVtaQ/mMsvjg==", + "dev": true + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -1168,6 +1204,15 @@ "lodash": "^4.17.11" } }, + "resolve": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1449,6 +1494,36 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, + "tslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", + "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.13.0", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index a4597ab..dd35141 100644 --- a/package.json +++ b/package.json @@ -2,20 +2,23 @@ "name": "btcpay", "version": "0.2.0", "description": "A nodejs client implementation for BTCPay", - "main": "index.js", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "tsc" + "build": "rimraf dist && tsc -p ./tsconfig.json", + "format": "npm run prettier -- --write", + "format:ci": "npm run prettier -- --check", + "lint": "tslint -p tsconfig.json -c tslint.json", + "prepare": "npm run build", + "prettier": "prettier 'src/**/*.ts' --single-quote --trailing-comma all", + "test": "npm run format:ci && npm run lint && echo \"###!!!Warning!!!### No tests exist! We ONLY checked formatting and linting!\"" }, "author": "Tim Akinbo ; Christoph Ott ", "license": "MIT", "dependencies": { - "@types/bs58": "^4.0.0", - "@types/elliptic": "^6.4.6", - "@types/node": "^11.13.5", - "@types/request": "^2.48.1", - "@types/request-promise": "^4.1.42", - "@types/underscore": "^1.8.14", "bs58": "^4.0.1", "elliptic": "^6.4.0", "request": "^2.85.0", @@ -23,8 +26,17 @@ "underscore": "^1.8.3" }, "devDependencies": { + "@types/bs58": "^4.0.0", + "@types/elliptic": "^6.4.6", + "@types/node": "^11.13.5", + "@types/request": "^2.48.1", + "@types/request-promise": "^4.1.42", + "@types/underscore": "^1.8.14", "eslint": "^5.16.0", + "prettier": "^1.17.1", + "rimraf": "^2.6.3", "ts-node": "^8.1.0", + "tslint": "^5.16.0", "typescript": "^3.4.4" } } diff --git a/src/core/client.ts b/src/core/client.ts index ba3cd56..14b2c33 100644 --- a/src/core/client.ts +++ b/src/core/client.ts @@ -10,27 +10,28 @@ export class BTCPayClient { private host: string; private kp: elliptic.ec.KeyPair; private tokens: any; - private client_id: string; - private user_agent: string; + private clientId: string; + private userAgent: string; private options: any; constructor(host: string, keypair: elliptic.ec.KeyPair, tokens: any) { this.host = host; this.kp = keypair; - this.tokens = tokens == undefined ? {} : tokens; - this.client_id = crypto.get_sin_from_key(keypair); - this.user_agent = 'node-btcpay'; + this.tokens = tokens === undefined ? {} : tokens; + this.clientId = crypto.get_sin_from_key(keypair); + this.userAgent = 'node-btcpay'; this.options = { headers: { 'Content-Type': 'application/json', Accept: 'application/json', - 'X-Accept-Version': '2.0.0' + 'User-Agent': this.userAgent, + 'X-Accept-Version': '2.0.0', }, - json: true + json: true, }; } - public async pair_client(code) { + public async pair_client(code: string): Promise { const re = new RegExp('^\\w{7,7}$'); if (!re.test(code)) { @@ -38,14 +39,14 @@ export class BTCPayClient { } const payload = { - id: this.client_id, - pairingCode: code + id: this.clientId, + pairingCode: code, }; try { const data = await this.unsigned_request('/tokens', payload); const _data = data[0]; - const _res = {}; + const _res: any = {}; _res[_data.facade] = _data.token; return _res; } catch (error) { @@ -53,10 +54,13 @@ export class BTCPayClient { } } - public async get_rates(currencyPairs, storeID): Promise { + public async get_rates( + currencyPairs: string[], + storeID: string, + ): Promise { const _params = { currencyPairs, - storeID + storeID, }; return this.signed_get_request('/rates', _params); @@ -73,14 +77,13 @@ export class BTCPayClient { throw 'Price must be a float'; } - return this.signed_post_request('/invoices', payload, token) as Invoice; + return this.signed_post_request('/invoices', payload, token) as Promise< + Invoice + >; } - public async get_invoice( - invoice_id: string, - token?: any - ): Promise { - return this.signed_get_request('/invoices/' + invoice_id, token); + public async get_invoice(invoiceId: string, token?: any): Promise { + return this.signed_get_request('/invoices/' + invoiceId, token); } public async get_invoices(params: any, token?: any): Promise { @@ -90,16 +93,16 @@ export class BTCPayClient { private create_signed_headers(uri: string, payload: string) { return { 'X-Identity': Buffer.from( - this.kp.getPublic().encodeCompressed() + this.kp.getPublic().encodeCompressed(), ).toString('hex'), - 'X-Signature': crypto.sign(uri + payload, this.kp).toString('hex') + 'X-Signature': crypto.sign(uri + payload, this.kp).toString('hex'), }; } private async signed_get_request( path: string, params: any, - token?: any + token?: any, ): Promise { const _token = token ? token : _.values(this.tokens)[0]; const _params = params ? params : {}; @@ -124,7 +127,7 @@ export class BTCPayClient { private async signed_post_request( path: string, payload: any, - token: any + token: any, ): Promise { const _token = token ? token : _.values(this.tokens)[0]; payload['token'] = _token; diff --git a/src/core/cryptography.ts b/src/core/cryptography.ts index 9526807..a138d13 100644 --- a/src/core/cryptography.ts +++ b/src/core/cryptography.ts @@ -11,14 +11,14 @@ export class Cryptography { } public static load_keypair( - buf: Buffer | string | elliptic.ec.KeyPair + buf: Buffer | string | elliptic.ec.KeyPair, ): elliptic.ec.KeyPair { return ec.keyFromPrivate(buf); } public static get_sin_from_key(kp: elliptic.ec.KeyPair): string { const pk: crypto.BinaryLike = Buffer.from( - kp.getPublic().encodeCompressed() + kp.getPublic().encodeCompressed(), ); const version: Buffer = Cryptography.get_version_from_compressed_key(pk); const checksum: Buffer = Cryptography.get_checksum_from_version(version); @@ -27,7 +27,7 @@ export class Cryptography { public static sign( message: crypto.BinaryLike, - kp: elliptic.ec.KeyPair + kp: elliptic.ec.KeyPair, ): Buffer { const digest = crypto .createHash('sha256') @@ -37,7 +37,7 @@ export class Cryptography { } private static get_version_from_compressed_key( - pk: crypto.BinaryLike + pk: crypto.BinaryLike, ): Buffer { const sh2 = crypto .createHash('sha256') @@ -51,7 +51,7 @@ export class Cryptography { return Buffer.concat([ Buffer.from('0F', 'hex'), Buffer.from('02', 'hex'), - rp + rp, ]); } diff --git a/src/index.ts b/src/index.ts index 7bfc5b6..b629efc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,6 @@ import { Cryptography } from './core/cryptography'; import { BTCPayClient } from './core/client'; +export { Invoice } from './models/invoice'; +export { Rate } from './models/rate'; export { Cryptography as crypto, BTCPayClient }; diff --git a/src/models/invoice.ts b/src/models/invoice.ts index 42b2fb8..40e73af 100644 --- a/src/models/invoice.ts +++ b/src/models/invoice.ts @@ -1 +1,68 @@ -export interface Invoice {} +export interface Invoice { + id: string; + token: string; + price: number; + currency: string; + orderId: string; + orderID?: string; + itemDesc: string; + itemCode: string; + notificationEmail: string; + notificationURL: string; + redirectURL: string; + paymentUrls?: any; + paymentCodes: any; + posData: string; + transactionSpeed: string; + fullNotifications: boolean; + extendedNotifications: boolean; + physical: boolean; + buyer: { + name: string; + address1: string; + address2: string; + locality: string; + region: string; + postalCode: string; + country: string; + email: string; + phone: string; + notify: boolean; + }; + url: string; + status: string; + btcPaid?: number; + amountPaid: number; + btcPrice?: number; + paymentSubtotals: any; + btcDue?: number; + paymentTotals: any; + minerFees: any; + invoiceTime: number; + expirationTime: number; + currentTime: string; // 'date' === string? + exceptionStatus: string | boolean; + rate?: number; + exRates?: any; + exchangeRates: any; + transactions: Array<{ + amount: number; + confirmations: number; + time: string; // 'date' === string? + receivedTime: string; // 'date' === string? + }>; + flags?: { + refundable: string; + }; + creditedOverpaymentAmounts: any; + refundInfo: Array<{ + supportRequest: string; + currency: string; + amounts: any; + }>; + transactionCurrency: string; + supportedTransactionCurrencies: any; + buyerProvidedInfo: { + selectedTransactionCurrency: any; + }; +} diff --git a/src/models/rate.ts b/src/models/rate.ts index 78de024..5a241bc 100644 --- a/src/models/rate.ts +++ b/src/models/rate.ts @@ -1 +1,5 @@ -export interface Rate {} +export interface Rate { + code: string; + name: string; + rate: number; +} diff --git a/tests/sample.js b/tests/sample.js index 332abeb..7afdade 100644 --- a/tests/sample.js +++ b/tests/sample.js @@ -5,5 +5,5 @@ const client = new btcpay.BTCPayClient('', keypair, { merchant: '' }); client .get_rates('BTC_USD', '') - .then((rates) => console.log(rates)) - .catch((err) => console.log(err)); + .then(rates => console.log(rates)) + .catch(err => console.log(err)); diff --git a/tests/sample.ts b/tests/sample.ts index bd3cdcb..383c99e 100644 --- a/tests/sample.ts +++ b/tests/sample.ts @@ -4,7 +4,7 @@ import { METHODS } from 'http'; const keypair = btcpay.crypto.load_keypair(Buffer.from('', 'hex')); const client = new btcpay.BTCPayClient('', keypair, { - merchant: '' + merchant: '', }); async function test() { diff --git a/tsconfig.json b/tsconfig.json index 27868ec..4ccefd4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,23 @@ { "compilerOptions": { + "target": "es2017", "module": "commonjs", - "esModuleInterop": true, - "target": "es6", - "moduleResolution": "node", - "sourceMap": true, + "strict": true, + "declaration": true, "outDir": "dist", - "declaration": true + "moduleResolution": "node", + "esModuleInterop": false }, - "include": ["src"], - "exclude": ["node_modules", "tests"], - "lib": ["es2015"] + "lib": [ + "es2015", + "node" + ], + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts", + "node_modules", + "tests" + ] } diff --git a/tslint.json b/tslint.json index 64aad90..6e2fd63 100644 --- a/tslint.json +++ b/tslint.json @@ -11,7 +11,6 @@ "interface-name": false, "jsdoc-format": true, "label-position": true, - "label-undefined": true, "max-line-length": [false, 140], "member-ordering": [ false, @@ -26,7 +25,6 @@ "no-construct": true, "no-constructor-vars": false, "no-debugger": false, - "no-duplicate-key": true, "no-shadowed-variable": false, "no-duplicate-variable": true, "no-empty": false, @@ -34,11 +32,8 @@ "no-require-imports": true, "no-string-literal": false, "no-switch-case-fall-through": false, - "no-trailing-comma": true, "no-trailing-whitespace": true, - "no-unreachable": true, "no-unused-expression": false, - "no-unused-variable": true, "no-use-before-declare": true, "no-var-keyword": true, "no-var-requires": false, @@ -72,7 +67,6 @@ "variable-declaration": "nospace" } ], - "use-strict": [true, "check-module", "check-function"], "variable-name": [true, "allow-leading-underscore"], "whitespace": [ false,