From 6e729dbb8fd3e5d437947e20f7399f22ad22859c Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 9 Jun 2020 13:51:05 +0800 Subject: [PATCH 01/14] chore: install prettier and replace tslint with eslint-ts --- .eslintignore | 6 +++ .eslintrc.js | 14 ++++++ .prettierrc | 8 +++ package.json | 9 +++- tslint.json | 135 -------------------------------------------------- 5 files changed, 35 insertions(+), 137 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .prettierrc delete mode 100644 tslint.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..537b7fa --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +# don't ever lint node_modules +node_modules +# don't lint build output (make sure it's set to your correct build folder name) +dist +# don't lint nyc coverage output +coverage diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..39e6753 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,14 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: [ + '@typescript-eslint', + ], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + 'prettier/@typescript-eslint', + 'plugin:prettier/recommended', + ], +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b281fec --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "printWidth": 100, + "tabWidth": 2, + "bracketSpacing": true, + "trailingComma": "es5", + "semi": false, + "singleQuote": true +} diff --git a/package.json b/package.json index 7e03c89..e83870a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tokenlon-mmsk", - "version": "0.6.0", + "version": "0.6.1-alpha.1", "description": "", "main": "lib/index.js", "types": "src/globals.d.ts", @@ -24,15 +24,20 @@ "homepage": "https://github.com/consenlabs/tokenlon-mmsk#readme", "devDependencies": { "@types/node": "10.11.5", + "eslint": "^7.2.0", + "eslint-config-prettier": "^6.11.0", + "eslint-plugin-prettier": "^3.1.3", "npm-run-all": "4.1.5", + "prettier": "^2.0.5", "ts-node": "7.0.1", - "tslint": "5.11.0", "typescript": "3.1.1" }, "dependencies": { "0x.js": "1.0.8", "@babel/runtime": "7.3.1", "@sentry/node": "4.5.3", + "@typescript-eslint/eslint-plugin": "^3.2.0", + "@typescript-eslint/parser": "^3.2.0", "axios": "0.19.0", "babel-polyfill": "6.26.0", "binance-api-node": "0.8.18", diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 1d61df5..0000000 --- a/tslint.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "rules": { - "member-access": false, - "no-any": false, - "no-inferrable-types": [ - false - ], - "no-internal-module": true, - "no-var-requires": true, - "typedef": [ - false - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - }, - { - "call-signature": "space", - "index-signature": "space", - "parameter": "space", - "property-declaration": "space", - "variable-declaration": "space" - } - ], - "ban": false, - "curly": false, - "forin": false, - "label-position": true, - "no-arg": true, - "no-bitwise": true, - "no-conditional-assignment": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-variable": true, - "no-empty": false, - "no-eval": true, - "no-null-keyword": false, - "no-shadowed-variable": false, - "no-string-literal": true, - "no-switch-case-fall-through": true, - "no-unused-expression": [ - true, - "allow-fast-null-checks" - ], - "no-use-before-declare": true, - "no-var-keyword": true, - "radix": true, - "switch-default": true, - "triple-equals": [ - true, - "allow-undefined-check" - ], - "eofline": false, - "indent": [ - true, - "spaces" - ], - "max-line-length": [ - false, - 150 - ], - "no-require-imports": false, - "no-trailing-whitespace": true, - "object-literal-sort-keys": false, - "trailing-comma": [ - true, - { - "multiline": "always", - "singleline": "never" - } - ], - "align": [ - true - ], - "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "interface-name": [ - false - ], - "jsdoc-format": false, - "no-consecutive-blank-lines": [ - true - ], - "no-parameter-properties": false, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-finally", - "check-whitespace" - ], - "quotemark": [ - true, - "single", - "jsx-double", - "avoid-escape" - ], - "semicolon": [ - true, - "never" - ], - "variable-name": [ - true, - "check-format", - "allow-pascal-case", - "allow-leading-underscore", - "ban-keywords" - ], - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ] - } -} \ No newline at end of file From 76b7b9ddecea25aef7eb4728a6ec38e28dd6731e Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 9 Jun 2020 16:57:56 +0800 Subject: [PATCH 02/14] refactor: only import minimal 0x dependencies --- package.json | 11 ++++++----- src/utils/ethereum.ts | 4 ++-- src/utils/format.ts | 4 ++-- src/utils/math.ts | 4 ++-- src/utils/order.ts | 4 ++-- src/utils/sign.ts | 4 ++-- src/utils/web3.ts | 4 ++-- src/validations/index.ts | 4 ++-- tsconfig.json | 4 ++-- 9 files changed, 22 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index e83870a..4e2215d 100644 --- a/package.json +++ b/package.json @@ -23,21 +23,22 @@ }, "homepage": "https://github.com/consenlabs/tokenlon-mmsk#readme", "devDependencies": { - "@types/node": "10.11.5", + "@types/node": "10.17.25", + "@typescript-eslint/eslint-plugin": "^3.2.0", + "@typescript-eslint/parser": "^3.2.0", "eslint": "^7.2.0", "eslint-config-prettier": "^6.11.0", "eslint-plugin-prettier": "^3.1.3", "npm-run-all": "4.1.5", "prettier": "^2.0.5", "ts-node": "7.0.1", - "typescript": "3.1.1" + "typescript": "^3.8.3" }, "dependencies": { - "0x.js": "1.0.8", + "@0xproject/order-utils": "^1.0.1", + "@0xproject/utils": "^2.0.0", "@babel/runtime": "7.3.1", "@sentry/node": "4.5.3", - "@typescript-eslint/eslint-plugin": "^3.2.0", - "@typescript-eslint/parser": "^3.2.0", "axios": "0.19.0", "babel-polyfill": "6.26.0", "binance-api-node": "0.8.18", diff --git a/src/utils/ethereum.ts b/src/utils/ethereum.ts index 3da8a85..297ac7d 100644 --- a/src/utils/ethereum.ts +++ b/src/utils/ethereum.ts @@ -1,4 +1,4 @@ -import { BigNumber } from '0x.js' +import { BigNumber } from '@0xproject/utils' import { toBN } from './math' import { web3RequestWrap } from './web3' import { addressWithout0x } from './address' @@ -18,4 +18,4 @@ export const getTokenBalance = ({ address, contractAddress }): Promise boolean, operate: (v) => any): any => { let result = {} @@ -36,4 +36,4 @@ export const fromUnitToDecimal = (balance, decimal, base) => { // precision + 1 的位置,进行四舍五入 export const roundAmount = (amount, precision) => { return toBN(Math.round(amount * Math.pow(10, precision))).dividedBy(Math.pow(10, precision)).toNumber() -} \ No newline at end of file +} diff --git a/src/utils/math.ts b/src/utils/math.ts index 677c02c..c88c510 100644 --- a/src/utils/math.ts +++ b/src/utils/math.ts @@ -1,7 +1,7 @@ -import { BigNumber } from '0x.js' +import { BigNumber } from '@0xproject/utils' export const toBN = obj => new BigNumber(obj) export const toFixed = (n, dp = 4, rm = 1): string => { return toBN(n).toFixed(dp, rm) -} \ No newline at end of file +} diff --git a/src/utils/order.ts b/src/utils/order.ts index 9b20fa2..d7b4a42 100644 --- a/src/utils/order.ts +++ b/src/utils/order.ts @@ -1,5 +1,5 @@ import { MarketMakerConfig, Token, TokenConfig } from '../types' -import { assetDataUtils, generatePseudoRandomSalt, orderHashUtils, signatureUtils, SignerType, SignatureType } from '0x.js' +import { assetDataUtils, generatePseudoRandomSalt, orderHashUtils, signatureUtils, SignerType, SignatureType } from '@0xproject/order-utils' import * as _ from 'lodash' import * as ethUtils from 'ethereumjs-util' import { toBN } from './math' @@ -140,4 +140,4 @@ export const getFormatedSignedOrder = (params: GetFormatedSignedOrderParams) => } return orderBNToString(signedOrder) -} \ No newline at end of file +} diff --git a/src/utils/sign.ts b/src/utils/sign.ts index ab40249..04516ba 100644 --- a/src/utils/sign.ts +++ b/src/utils/sign.ts @@ -1,5 +1,5 @@ import * as ethUtil from 'ethereumjs-util' -import { ECSignature, signatureUtils, SignerType } from '0x.js' +import { ECSignature, signatureUtils, SignerType } from '@0xproject/order-utils' import { leftPadWith0 } from './helper' import * as _ from 'lodash' @@ -141,4 +141,4 @@ export const ecSignOrderHash = ( } throw new Error('InvalidSignature') -} \ No newline at end of file +} diff --git a/src/utils/web3.ts b/src/utils/web3.ts index ea91a2f..f017c4c 100644 --- a/src/utils/web3.ts +++ b/src/utils/web3.ts @@ -1,6 +1,6 @@ import * as Web3Export from 'web3' import * as _ from 'lodash' -import { BigNumber } from '0x.js' +import { BigNumber } from '@0xproject/utils' import { config } from '../config' const Web3 = Web3Export.default ? Web3Export.default : Web3Export @@ -25,4 +25,4 @@ export const web3RequestWrap = async (handler: Handler) => { } throw error ? error : new Error('unknown web3 error') -} \ No newline at end of file +} diff --git a/src/validations/index.ts b/src/validations/index.ts index 26b0012..4d9cd44 100644 --- a/src/validations/index.ts +++ b/src/validations/index.ts @@ -2,7 +2,7 @@ import * as _ from 'lodash' import * as Web3Export from 'web3' import { Wallet } from '../types' import * as ethUtils from 'ethereumjs-util' -import { BigNumber } from '0x.js' +import { BigNumber } from '@0xproject/utils' import { isSupportedBaseQuote, getSupportedTokens } from '../utils/token' const Web3 = Web3Export.default ? Web3Export.default : Web3Export @@ -53,4 +53,4 @@ export const checkParams = (query, isNewOrderAPI?: boolean) => { result: !message, message, } -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index 8256785..d597be9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "sourceMap": true, "outDir": "lib", "rootDir": "src", @@ -27,4 +27,4 @@ "exclude": [ "node_modules" ] -} \ No newline at end of file +} From 3c99148a437b6555c27273227cc8da616ca879cc Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 9 Jun 2020 16:59:38 +0800 Subject: [PATCH 03/14] feature: add http server and client logging --- package.json | 2 ++ src/request/_request.ts | 7 ++++++- src/start.ts | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4e2215d..3057192 100644 --- a/package.json +++ b/package.json @@ -40,11 +40,13 @@ "@babel/runtime": "7.3.1", "@sentry/node": "4.5.3", "axios": "0.19.0", + "axios-logger": "^2.3.1", "babel-polyfill": "6.26.0", "binance-api-node": "0.8.18", "keythereum": "1.0.4", "koa": "2.5.3", "koa-bodyparser": "4.2.1", + "koa-logger": "^3.2.1", "koa-router": "7.4.0", "lodash": "4.17.14", "readline-sync": "1.4.9", diff --git a/src/request/_request.ts b/src/request/_request.ts index d149686..b3cb7c1 100644 --- a/src/request/_request.ts +++ b/src/request/_request.ts @@ -1,7 +1,12 @@ import axios from 'axios' +import * as AxiosLogger from 'axios-logger' import * as _ from 'lodash' import { REQUEST_TIMEOUT } from '../constants' +const client = axios.create() +client.interceptors.request.use(AxiosLogger.requestLogger) +client.interceptors.response.use(AxiosLogger.responseLogger) + // `validateStatus` defines whether to resolve or reject the promise for a given // HTTP response status code. If `validateStatus` returns `true` (or is set to `null` // or `undefined`), the promise will be resolved; otherwise, the promise will be rejected. @@ -42,7 +47,7 @@ export const sendRequest = (config): Promise => { ...config, } return new Promise((resolve, reject) => { - axios(rConfig).then(res => { + client(rConfig).then(res => { if (res.data) { resolve(res.data) } else { diff --git a/src/start.ts b/src/start.ts index 141c024..200b375 100644 --- a/src/start.ts +++ b/src/start.ts @@ -3,6 +3,7 @@ import * as Sentry from '@sentry/node' import * as Koa from 'koa' import * as Router from 'koa-router' import * as Bodyparser from 'koa-bodyparser' +import * as logger from 'koa-logger' import { getRate, newOrder, getSupportedTokenList, getBalances, getBalance, getOrderState, getOrdersHistory, dealOrder, exceptionOrder, version } from './router' import { setConfig } from './config' import { ConfigForStart } from './types' @@ -92,6 +93,7 @@ export const startMMSK = async (config: ConfigForStart) => { await next() }) .use(Bodyparser()) + .use(logger()) .use(router.routes()) .use(router.allowedMethods()) @@ -111,4 +113,4 @@ export const startMMSK = async (config: ConfigForStart) => { console.log(e) process.exit(0) } -} \ No newline at end of file +} From 9d93bd1ceb1bafbf4b04e3c88c963aa805180aae Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 9 Jun 2020 17:00:20 +0800 Subject: [PATCH 04/14] feature: add mock server for benchmark --- app/start.js | 2 + benchmark/MockServer.ts | 133 ++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 3 files changed, 137 insertions(+) create mode 100644 benchmark/MockServer.ts diff --git a/app/start.js b/app/start.js index 001d14c..b33fe6f 100644 --- a/app/start.js +++ b/app/start.js @@ -1,3 +1,5 @@ +require('dotenv').config() + const mmConf = require('./mmConfig') const mmsk = require('../lib') diff --git a/benchmark/MockServer.ts b/benchmark/MockServer.ts new file mode 100644 index 0000000..f5db50c --- /dev/null +++ b/benchmark/MockServer.ts @@ -0,0 +1,133 @@ +import * as Koa from 'koa' +import * as Router from 'koa-router' +import * as BodyParser from 'koa-bodyparser' +import * as logger from 'koa-logger' +import * as JsonRPC from '@koalex/koa-json-rpc' + +function makeMarketMakerRounter(): Router { + const router = new Router() + router.get('/pairs', function(ctx, _next) { + ctx.body = JSON.stringify({ + 'result': true, + 'pairs': [ + 'ETH/DAI', + ], + }) + }) + router.get('/indicativePrice', function(ctx, _next) { + ctx.body = JSON.stringify({ + 'result': true, + 'exchangeable': true, + 'price': 0.00017508, + 'minAmount': 0.002, + 'maxAmount': 100, + }) + }) + router.get('/price', function(ctx, _next) { + ctx.body = JSON.stringify({ + 'result': true, + 'exchangeable': true, + 'price': 0.00017508, + 'minAmount': 0.0002, + 'maxAmount': 100, + 'quoteId': 'asfadsf-dsfsdf-ggsd-qwe-rgjty', + }) + }) + router.get('/deal', function(ctx, _next) { + ctx.body = JSON.stringify({ result: true }) + }) + return router +} + +function createRPCHandler(): JsonRPC { + const endpoint = new JsonRPC({ + bodyParser: BodyParser({ + onerror: (_err, ctx) => { + ctx.status = 200; + ctx.body = JsonRPC.parseError; + } + }) + }) + endpoint.method('tokenlon.getMarketMakerConfig', (ctx, _next) => { + ctx.body = JSON.stringify({ + "mmId": 1, + "networkId": 3000, + "erc20ProxyContractAddress": "0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e", + "exchangeContractAddress": "0x30589010550762d2f0d06f650d8e8b6ade6dbf4b", + "forwarderContractAddress": "0xd85e2fa7e7e252b27b01bf0d65c946959d2f45b8", + "zrxContractAddress": "0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa", + "tokenlonExchangeContractAddress": "0xc23dc48e847ea67cde9a93d0df242f9584abc90d", + "wethContractAddress": "0xd0a1e359811322d97991e03f863a0c30c2cf029c", + "userProxyContractAddress": "0x97959853a0fb9a28432f1d4f46654fe524a12d81", + "orderExpirationSeconds": 600, + "mmProxyContractAddress": "0x974afc6906cdeb17f163b7a5a2d2a59aa488b94e", + "feeFactor": 30 + }) + }) + endpoint.method('auth.getMMJwtToken', (ctx, _next) => { + ctx.body = JSON.stringify("TODO") + }) + + endpoint.method('tokenlon.getTokenList', (ctx, _next) => { + ctx.body = JSON.stringify([ + { + "symbol": "ETH", + "logo": "https://cdn.example.com/mainnet-production/tokens/icons/eth%403x.png", + "contractAddress": "0x0000000000000000000000000000000000000000", + "decimal": 18, + "precision": 4, + "minTradeAmount": 1E-7, + "maxTradeAmount": 1E+1 + }, + { + "symbol": "DAI", + "logo": "https://cdn.example.com/mainnet-production/exchange-pairs/DAI.png", + "contractAddress": "0x5c964665b6379527b625be996020d861f27aa31d", + "decimal": 18, + "precision": 4, + "minTradeAmount": 0.001, + "maxTradeAmount": 1E+4 + }]) + }) + + endpoint.method('tokenlon.getTokenConfigsForMM', (ctx, _next) => { + ctx.body = JSON.stringify("TODO") + }) + + endpoint.method('tokenlon.getOrdersHistoryForMM', (ctx, _next) => { + ctx.body = JSON.stringify("TODO") + }) + + endpoint.method('tokenlon.getOrderStateForMM', (ctx, _next) => { + ctx.body = JSON.stringify("TODO") + }) + + endpoint.method('hello', (ctx, _next) => { + // ctx.jsonrpc available + /* + ctx.jsonrpc.request + ctx.jsonrpc.id + ctx.jsonrpc.method [[Get]] + ctx.jsonrpc.params [[Get]] + ctx.jsonrpc.response + ctx.jsonrpc.result + ctx.jsonrpc.error + ctx.jsonrpc.code + ctx.jsonrpc.message + ctx.jsonrpc.data + */ + ctx.body = 'Hello world!' + }) + + return endpoint +} + +const app = new Koa() +const router = makeMarketMakerRounter() +router.post('/rpc', createRPCHandler().middleware) +app + .use(BodyParser()) + .use(logger()) + .use(router.routes()) + .use(router.allowedMethods()) +app.listen(8088) diff --git a/package.json b/package.json index 3057192..f59a55a 100644 --- a/package.json +++ b/package.json @@ -38,11 +38,13 @@ "@0xproject/order-utils": "^1.0.1", "@0xproject/utils": "^2.0.0", "@babel/runtime": "7.3.1", + "@koalex/koa-json-rpc": "^1.0.3", "@sentry/node": "4.5.3", "axios": "0.19.0", "axios-logger": "^2.3.1", "babel-polyfill": "6.26.0", "binance-api-node": "0.8.18", + "dotenv": "^8.2.0", "keythereum": "1.0.4", "koa": "2.5.3", "koa-bodyparser": "4.2.1", From b890ea77dc4f55dc2e687e70eed0ddc8c9381887 Mon Sep 17 00:00:00 2001 From: Kai Date: Fri, 12 Jun 2020 11:24:29 +0800 Subject: [PATCH 05/14] feat: add benchmark scripts --- .gitignore | 3 ++- benchmark/MockServer.ts | 42 +++++++++++++++++++++++++--------------- benchmark/README.md | 11 +++++++++++ benchmark/Start.js | 23 ++++++++++++++++++++++ benchmark/bench.sh | 4 ++++ src/utils/token.ts | 29 ++++++++++++++++++++------- src/validations/index.ts | 2 +- tsconfig.json | 2 +- 8 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 benchmark/README.md create mode 100644 benchmark/Start.js create mode 100644 benchmark/bench.sh diff --git a/.gitignore b/.gitignore index ebace73..88b7762 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ npm-debug.log npm-debug.log.* yarn-error.log package-lock.json -lib \ No newline at end of file +lib +.env diff --git a/benchmark/MockServer.ts b/benchmark/MockServer.ts index f5db50c..dc66451 100644 --- a/benchmark/MockServer.ts +++ b/benchmark/MockServer.ts @@ -7,34 +7,34 @@ import * as JsonRPC from '@koalex/koa-json-rpc' function makeMarketMakerRounter(): Router { const router = new Router() router.get('/pairs', function(ctx, _next) { - ctx.body = JSON.stringify({ + ctx.body = { 'result': true, 'pairs': [ - 'ETH/DAI', + 'DAI/ETH', ], - }) + } }) router.get('/indicativePrice', function(ctx, _next) { - ctx.body = JSON.stringify({ + ctx.body = { 'result': true, 'exchangeable': true, 'price': 0.00017508, 'minAmount': 0.002, 'maxAmount': 100, - }) + } }) router.get('/price', function(ctx, _next) { - ctx.body = JSON.stringify({ + ctx.body = { 'result': true, 'exchangeable': true, 'price': 0.00017508, 'minAmount': 0.0002, 'maxAmount': 100, 'quoteId': 'asfadsf-dsfsdf-ggsd-qwe-rgjty', - }) + } }) router.get('/deal', function(ctx, _next) { - ctx.body = JSON.stringify({ result: true }) + ctx.body = { result: true } }) return router } @@ -49,7 +49,8 @@ function createRPCHandler(): JsonRPC { }) }) endpoint.method('tokenlon.getMarketMakerConfig', (ctx, _next) => { - ctx.body = JSON.stringify({ + // test address on kovan network + ctx.body = { "mmId": 1, "networkId": 3000, "erc20ProxyContractAddress": "0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e", @@ -62,14 +63,14 @@ function createRPCHandler(): JsonRPC { "orderExpirationSeconds": 600, "mmProxyContractAddress": "0x974afc6906cdeb17f163b7a5a2d2a59aa488b94e", "feeFactor": 30 - }) + } }) endpoint.method('auth.getMMJwtToken', (ctx, _next) => { - ctx.body = JSON.stringify("TODO") + ctx.body = "TODO" }) endpoint.method('tokenlon.getTokenList', (ctx, _next) => { - ctx.body = JSON.stringify([ + ctx.body = [ { "symbol": "ETH", "logo": "https://cdn.example.com/mainnet-production/tokens/icons/eth%403x.png", @@ -87,19 +88,28 @@ function createRPCHandler(): JsonRPC { "precision": 4, "minTradeAmount": 0.001, "maxTradeAmount": 1E+4 - }]) + }] }) endpoint.method('tokenlon.getTokenConfigsForMM', (ctx, _next) => { - ctx.body = JSON.stringify("TODO") + ctx.body = [ + { + "symbol": "ETH", + "feeFactor": 30 + }, + { + "symbol": "DAI", + "feeFactor": 30 + } + ] }) endpoint.method('tokenlon.getOrdersHistoryForMM', (ctx, _next) => { - ctx.body = JSON.stringify("TODO") + ctx.body = "TODO" }) endpoint.method('tokenlon.getOrderStateForMM', (ctx, _next) => { - ctx.body = JSON.stringify("TODO") + ctx.body = "TODO" }) endpoint.method('hello', (ctx, _next) => { diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 0000000..fcf68ff --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,11 @@ +# Benchmark + +```shell script +vim .env # <- prepare .env config file, see app/mmConfig for config items +npm instlal -g ganache-cli # <- install ganache chain +ganache-cli -i 3000 # <- launch ganache chain +npm install # <- install dependency +ts-node benchmark/MockServer.ts # <- launch mock server +node --inspect benchmark/Start.js # <- launch mmsk server +bash benchmark/bench.sh # <- run wrk +``` diff --git a/benchmark/Start.js b/benchmark/Start.js new file mode 100644 index 0000000..6afc21a --- /dev/null +++ b/benchmark/Start.js @@ -0,0 +1,23 @@ +//import { startMMSK } from '../src' +//import { config as loadEnvConfig } from 'dotenv' + +const startMMSK = require("../lib").startMMSK +const loadEnvConfig = require("dotenv").config + +async function main() { + loadEnvConfig() + startMMSK({ + EXCHANGE_URL: process.env.EXCHANGE_URL, + WEBSOCKET_URL: process.env.WEBSOCKET_URL, + PROVIDER_URL: process.env.PROVIDER_URL, + USE_KEYSTORE: false, + WALLET_ADDRESS: process.env.WALLET_ADDRESS, + WALLET_PRIVATE_KEY: process.env.WALLET_PRIVATE_KEY, + MMSK_SERVER_PORT: 8080, + USE_ZERORPC: false, + HTTP_SERVER_ENDPOINT: process.env.HTTP_SERVER_ENDPOINT, + NODE_ENV: 'DEVELOPMENT', + }) +} + +main().catch(console.error) diff --git a/benchmark/bench.sh b/benchmark/bench.sh new file mode 100644 index 0000000..c0e6fd1 --- /dev/null +++ b/benchmark/bench.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +wrk -t4 -c500 -d30s \ + "http://127.0.0.1:8080/newOrder?base=DAI"e=ETH&side=BUY&amount=1&userAddr=0xaaaaaaaaaa222222222233333333334444444444&uniqId=tqrcftxg&feefactor=0" diff --git a/src/utils/token.ts b/src/utils/token.ts index 66db04d..eaa00f7 100644 --- a/src/utils/token.ts +++ b/src/utils/token.ts @@ -1,4 +1,4 @@ -import * as _ from 'lodash' +import { fromPairs } from 'lodash' import { updaterStack } from '../utils/intervalUpdater' import { SupportedToken } from '../types' @@ -33,7 +33,7 @@ export const getSupportedTokens = (): SupportedToken[] => { const tokenStack = transferPairStrArrToTokenStack(pairsFromMMUpdater.cacheResult) const tokenList = tokenListFromImtokenUpdater.cacheResult const result = [] - tokenList.forEach(token => { + for (const token of tokenList) { const { symbol } = token const opposites = tokenStack[symbol] if (opposites && opposites.length) { @@ -42,7 +42,7 @@ export const getSupportedTokens = (): SupportedToken[] => { opposites: opposites.filter(symbol => !!tokenList.find(t => t.symbol === symbol)), }) } - }) + } return result } @@ -57,18 +57,33 @@ export const getTokenBySymbol = (tokens, symbol) => { } // 处理接口大小写情况,转换为系统设定格式 -export const translateBaseQuote = (baseQuote) => { +export const translateBaseQuote = (pair) => { + const tokens = fromPairs(getSupportedTokens().map(t => [t.symbol.toUpperCase(), t.symbol])) + + if (typeof pair.base === 'string') { + const upperBase = pair.base.toUpperCase() + const sym = tokens[upperBase] + if (sym) pair.base = sym + } + if (typeof pair.quote === 'string') { + const upperQuote = pair.quote.toUpperCase() + const sym = tokens[upperQuote] + if (sym) pair.quote = sym + } +} + +export const translateBaseQuote__ = (baseQuote) => { const tokens = getSupportedTokens() - if (_.isString(baseQuote.base)) { + if (typeof baseQuote.base === 'string') { const found = tokens.find(t => t.symbol.toUpperCase() === baseQuote.base.toUpperCase()) if (found) { baseQuote.base = found.symbol } } - if (_.isString(baseQuote.quote)) { + if (typeof baseQuote.quote === 'string') { const found = tokens.find(t => t.symbol.toUpperCase() === baseQuote.quote.toUpperCase()) if (found) { baseQuote.quote = found.symbol } } -} \ No newline at end of file +} diff --git a/src/validations/index.ts b/src/validations/index.ts index 4d9cd44..fc39a69 100644 --- a/src/validations/index.ts +++ b/src/validations/index.ts @@ -7,7 +7,7 @@ import { isSupportedBaseQuote, getSupportedTokens } from '../utils/token' const Web3 = Web3Export.default ? Web3Export.default : Web3Export -export const isValidWallet = (wallet: Wallet) => { +export const isValidWallet = (wallet: Wallet): boolean => { if (!wallet) return false const { address, privateKey } = wallet if (!Web3.utils.isAddress(address)) return false diff --git a/tsconfig.json b/tsconfig.json index d597be9..3a64b8c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es6", + "target": "es5", "sourceMap": true, "outDir": "lib", "rootDir": "src", From f06b64cb04a134fbef11e24be61152f50342f796 Mon Sep 17 00:00:00 2001 From: Kai Date: Mon, 15 Jun 2020 11:38:23 +0800 Subject: [PATCH 06/14] feat: use cluster to run server --- app/start.js | 21 ++++++++++++++++++--- benchmark/Start.js | 23 +++++++++++++++++++---- benchmark/bench.sh | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/app/start.js b/app/start.js index b33fe6f..a02c479 100644 --- a/app/start.js +++ b/app/start.js @@ -1,6 +1,21 @@ -require('dotenv').config() - const mmConf = require('./mmConfig') const mmsk = require('../lib') -mmsk.startMMSK(mmConf) +const cluster = require('cluster') +const numCPUs = require('os').cpus().length + +if (cluster.isMaster) { + console.log(`Master ${process.pid} is running`); + + // Fork workers. + for (let i = 0; i < numCPUs; i++) { + cluster.fork() + } + + cluster.on('exit', (worker, code, signal) => { + console.log(`worker ${worker.process.pid} died`) + }) +} else { + mmsk.startMMSK(mmConf) + console.log(`Worker ${process.pid} started`) +} diff --git a/benchmark/Start.js b/benchmark/Start.js index 6afc21a..af341e1 100644 --- a/benchmark/Start.js +++ b/benchmark/Start.js @@ -1,6 +1,3 @@ -//import { startMMSK } from '../src' -//import { config as loadEnvConfig } from 'dotenv' - const startMMSK = require("../lib").startMMSK const loadEnvConfig = require("dotenv").config @@ -20,4 +17,22 @@ async function main() { }) } -main().catch(console.error) +const cluster = require('cluster') +const numCPUs = require('os').cpus().length + +if (cluster.isMaster) { + console.log(`Master ${process.pid} is running`); + + // Fork workers. + for (let i = 0; i < numCPUs; i++) { + cluster.fork() + } + + cluster.on('exit', (worker, code, signal) => { + console.log(`worker ${worker.process.pid} died`) + }) +} else { + main().catch(console.error) + + console.log(`Worker ${process.pid} started`) +} diff --git a/benchmark/bench.sh b/benchmark/bench.sh index c0e6fd1..1e20b34 100644 --- a/benchmark/bench.sh +++ b/benchmark/bench.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -wrk -t4 -c500 -d30s \ +wrk -t4 -c64 -d10s \ "http://127.0.0.1:8080/newOrder?base=DAI"e=ETH&side=BUY&amount=1&userAddr=0xaaaaaaaaaa222222222233333333334444444444&uniqId=tqrcftxg&feefactor=0" From aefb9b560af0901f468998b1b3b0a388c4ad9d8e Mon Sep 17 00:00:00 2001 From: Kai Date: Mon, 15 Jun 2020 15:30:58 +0800 Subject: [PATCH 07/14] refactor: tweak request log format --- src/start.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/start.ts b/src/start.ts index 200b375..5fa1a12 100644 --- a/src/start.ts +++ b/src/start.ts @@ -93,7 +93,14 @@ export const startMMSK = async (config: ConfigForStart) => { await next() }) .use(Bodyparser()) - .use(logger()) + .use(logger((_str, args) => { + if (args.length > 3) { // dont log inbound request + args.shift(0) + args.unshift("INFO") + args.unshift((new Date()).toISOString()) + console.log(args.join(" ")) + } + })) .use(router.routes()) .use(router.allowedMethods()) From 599fc9f8fa7412388b3b5ba5ad1b4ddbb64810eb Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 17 Jun 2020 15:13:31 +0800 Subject: [PATCH 08/14] test: add unit test for symobol convert function --- package.json | 13 ++++++---- src/utils/token.ts | 9 +++++-- test/utils.spec.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 test/utils.spec.ts diff --git a/package.json b/package.json index f59a55a..993d973 100644 --- a/package.json +++ b/package.json @@ -11,24 +11,29 @@ "author": "imToken PTE. LTD.", "license": "MIT", "scripts": { - "watch": "tsc -w", - "clean": "rm -rf ./lib", - "build:commonjs": "tsc", "build": "run-s clean build:commonjs", + "build:commonjs": "tsc", + "check": "node ./app/check.js", + "clean": "rm -rf ./lib", "start": "node ./app/start.js", - "check": "node ./app/check.js" + "test": "mocha -r ts-node/register test/**/*.spec.ts", + "watch": "tsc -w" }, "bugs": { "url": "https://github.com/consenlabs/tokenlon-mmsk/issues" }, "homepage": "https://github.com/consenlabs/tokenlon-mmsk#readme", "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", "@types/node": "10.17.25", "@typescript-eslint/eslint-plugin": "^3.2.0", "@typescript-eslint/parser": "^3.2.0", + "chai": "^4.2.0", "eslint": "^7.2.0", "eslint-config-prettier": "^6.11.0", "eslint-plugin-prettier": "^3.1.3", + "mocha": "^8.0.1", "npm-run-all": "4.1.5", "prettier": "^2.0.5", "ts-node": "7.0.1", diff --git a/src/utils/token.ts b/src/utils/token.ts index eaa00f7..3704dfa 100644 --- a/src/utils/token.ts +++ b/src/utils/token.ts @@ -57,8 +57,11 @@ export const getTokenBySymbol = (tokens, symbol) => { } // 处理接口大小写情况,转换为系统设定格式 -export const translateBaseQuote = (pair) => { - const tokens = fromPairs(getSupportedTokens().map(t => [t.symbol.toUpperCase(), t.symbol])) +export const translateBaseQuote = (pair, stdTokens = null) => { + if (stdTokens == null) { + stdTokens = getSupportedTokens() + } + const tokens = fromPairs(stdTokens.map(t => [t.symbol.toUpperCase(), t.symbol])) if (typeof pair.base === 'string') { const upperBase = pair.base.toUpperCase() @@ -70,6 +73,8 @@ export const translateBaseQuote = (pair) => { const sym = tokens[upperQuote] if (sym) pair.quote = sym } + + return pair } export const translateBaseQuote__ = (baseQuote) => { diff --git a/test/utils.spec.ts b/test/utils.spec.ts new file mode 100644 index 0000000..19b3706 --- /dev/null +++ b/test/utils.spec.ts @@ -0,0 +1,59 @@ +import { expect } from 'chai'; +import 'mocha' +import { translateBaseQuote } from '../src/utils/token' + +const supportTokens = [ + { + symbol: 'ETH', + logo: 'https://cdn.example.com/eth.png', + contractAddress: '0x0000000000000000000000000000000000000000', + decimal: 18, + precision: 4, + minTradeAmount: 1e-7, + maxTradeAmount: 10, + opposites: ['DAI', 'imBTC'], + }, + { + symbol: 'DAI', + logo: 'https://cdn.example.com/dai.png', + contractAddress: '0x5c964665b6379527b625be996020d861f27aa31d', + decimal: 18, + precision: 4, + minTradeAmount: 0.001, + maxTradeAmount: 10000, + opposites: ['ETH'], + }, + { + symbol: 'imBTC', + logo: 'https://cdn.example.com/dai.png', + contractAddress: '0x5c964665b6379527b625be996020d861f27aa31d', + decimal: 18, + precision: 4, + minTradeAmount: 0.001, + maxTradeAmount: 10000, + opposites: ['ETH'], + }, +] + +describe('translateBaseQuote()', function() { + it('does not change correct symbol', function() { + let pair = { base: 'DAI', quote: 'ETH' } + expect(translateBaseQuote(pair, supportTokens)).to.eql({ + base: 'DAI', quote: 'ETH', + }) + }) + + it('correct symbol in pair', function() { + let pair = { base: 'DAI', quote: 'Eth' } + expect(translateBaseQuote(pair, supportTokens)).to.eql({ + base: 'DAI', quote: 'ETH', + }) + }) + + it('correct symbol case in pair', function() { + let pair = { base: 'IMBTC', quote: 'ETH' } + expect(translateBaseQuote(pair, supportTokens)).to.eql({ + base: 'imBTC', quote: 'ETH', + }) + }) +}) From 0dc98eacbf33c95d68028cc4704c2cf0bc733371 Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 17 Jun 2020 15:15:07 +0800 Subject: [PATCH 09/14] chore: limit parallels process to avoid take too much resource --- app/start.js | 3 ++- benchmark/Start.js | 3 ++- benchmark/bench.sh | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/start.js b/app/start.js index a02c479..43cd7e5 100644 --- a/app/start.js +++ b/app/start.js @@ -3,12 +3,13 @@ const mmsk = require('../lib') const cluster = require('cluster') const numCPUs = require('os').cpus().length +const parallels = numCPUs > 8 ? 8 : numCPUs if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // Fork workers. - for (let i = 0; i < numCPUs; i++) { + for (let i = 0; i < parallels; i++) { cluster.fork() } diff --git a/benchmark/Start.js b/benchmark/Start.js index af341e1..655d49d 100644 --- a/benchmark/Start.js +++ b/benchmark/Start.js @@ -19,12 +19,13 @@ async function main() { const cluster = require('cluster') const numCPUs = require('os').cpus().length +const parallels = numCPUs > 8 ? 8 : numCPUs if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // Fork workers. - for (let i = 0; i < numCPUs; i++) { + for (let i = 0; i < parallels; i++) { cluster.fork() } diff --git a/benchmark/bench.sh b/benchmark/bench.sh index 1e20b34..ea66e71 100644 --- a/benchmark/bench.sh +++ b/benchmark/bench.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -wrk -t4 -c64 -d10s \ +wrk -t8 -c128 -d10s \ "http://127.0.0.1:8080/newOrder?base=DAI"e=ETH&side=BUY&amount=1&userAddr=0xaaaaaaaaaa222222222233333333334444444444&uniqId=tqrcftxg&feefactor=0" From 01d98a0fa6631509f8dadff7b65c97ba570ac9dc Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 17 Jun 2020 15:58:37 +0800 Subject: [PATCH 10/14] feat: avoid to write null result to cache --- src/utils/intervalUpdater/intervalUpdater.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/utils/intervalUpdater/intervalUpdater.ts b/src/utils/intervalUpdater/intervalUpdater.ts index 4ff1c12..5330ca3 100644 --- a/src/utils/intervalUpdater/intervalUpdater.ts +++ b/src/utils/intervalUpdater/intervalUpdater.ts @@ -24,7 +24,10 @@ export default class IntervalUpdater { intervalUpdater = () => { setTimeout(async () => { try { - this.cacheResult = await this.updater() + const result = await this.updater() + if (result != null) { + this.cacheResult = result + } } catch (error) { tracker.captureException(error) tracker.captureEvent({ @@ -41,8 +44,11 @@ export default class IntervalUpdater { } start = async () => { - this.cacheResult = await this.updater() + const result = await this.updater() + if (result != null) { + this.cacheResult = result + } this.intervalUpdater() return this.cacheResult } -} \ No newline at end of file +} From fc185b3e09a1f89f1306f71b112edb3e1af2ab70 Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 17 Jun 2020 16:09:17 +0800 Subject: [PATCH 11/14] refactor: simplify the axios logger import statement --- src/request/_request.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/request/_request.ts b/src/request/_request.ts index b3cb7c1..9a1c056 100644 --- a/src/request/_request.ts +++ b/src/request/_request.ts @@ -1,11 +1,11 @@ import axios from 'axios' -import * as AxiosLogger from 'axios-logger' +import { requestLogger, responseLogger } from 'axios-logger' import * as _ from 'lodash' import { REQUEST_TIMEOUT } from '../constants' const client = axios.create() -client.interceptors.request.use(AxiosLogger.requestLogger) -client.interceptors.response.use(AxiosLogger.responseLogger) +client.interceptors.request.use(requestLogger) +client.interceptors.response.use(responseLogger) // `validateStatus` defines whether to resolve or reject the promise for a given // HTTP response status code. If `validateStatus` returns `true` (or is set to `null` From 265353ac4fefb9d07379dfe4c85be3c58b828196 Mon Sep 17 00:00:00 2001 From: Kai Date: Fri, 19 Jun 2020 17:28:11 +0800 Subject: [PATCH 12/14] chore: bump version in http handler --- src/router/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/router/version.ts b/src/router/version.ts index 2ca72ce..d8b62c7 100644 --- a/src/router/version.ts +++ b/src/router/version.ts @@ -1,6 +1,6 @@ export const version = (ctx) => { ctx.body = { result: true, - version: '0.6.1', + version: '0.6.2', } -} \ No newline at end of file +} From 74c6c1c185eefe149049f893c5cee16f96cd3755 Mon Sep 17 00:00:00 2001 From: Kai Date: Fri, 19 Jun 2020 17:49:40 +0800 Subject: [PATCH 13/14] test: fix unit tests and setup github action ci --- .github/workflows/ci.yml | 33 +++++++++++++++++++++++++++++++++ package.json | 2 +- src/utils/helper.ts | 5 +++-- test/utils.spec.ts | 21 +++++++++++---------- 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7aa4e98 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: Node.js CI + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [8.x, 10.x, 12.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Cache Node.js modules + uses: actions/cache@v1 + with: + # npm cache files are stored in `~/.npm` on Linux/macOS + path: ~/.npm + key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.OS }}-node- + ${{ runner.OS }}- + - run: npm install + - run: npm run build --if-present + - run: npm test + env: + CI: true diff --git a/package.json b/package.json index a3af1d4..02c2e92 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "check": "node ./app/check.js", "clean": "rm -rf ./lib", "start": "node ./app/start.js", - "test": "mocha -r ts-node/register test/**/*.spec.ts", + "test": "mocha --exit -r ts-node/register test/**/*.spec.ts", "watch": "tsc -w" }, "bugs": { diff --git a/src/utils/helper.ts b/src/utils/helper.ts index b549974..4b0017f 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -2,6 +2,7 @@ import { updaterStack } from './intervalUpdater' import { roundAmount } from './format' import { QueryInterface } from '../router/interface' import { getSupportedTokens } from './token' +import { SupportedToken } from '../types' export const leftPadWith0 = (str, len) => { str = str + '' @@ -32,8 +33,8 @@ function calculateFeeFactor(baseSymbol: string, factor: number | null): number { return result } -function ensureCorrectSymbolCase(query: QueryInterface): QueryInterface { - const tokens = getSupportedTokens() +export function ensureCorrectSymbolCase(query: QueryInterface, supportedTokens: SupportedToken[] = null): QueryInterface { + const tokens = supportedTokens || getSupportedTokens() const result = { ...query } if (typeof query.base === 'string') { diff --git a/test/utils.spec.ts b/test/utils.spec.ts index 19b3706..deeed29 100644 --- a/test/utils.spec.ts +++ b/test/utils.spec.ts @@ -1,6 +1,7 @@ import { expect } from 'chai'; import 'mocha' -import { translateBaseQuote } from '../src/utils/token' +import { ensureCorrectSymbolCase } from '../src/utils/helper' +import { QueryInterface } from '../src/router/interface' const supportTokens = [ { @@ -37,23 +38,23 @@ const supportTokens = [ describe('translateBaseQuote()', function() { it('does not change correct symbol', function() { - let pair = { base: 'DAI', quote: 'ETH' } - expect(translateBaseQuote(pair, supportTokens)).to.eql({ - base: 'DAI', quote: 'ETH', + let pair: QueryInterface = { base: 'DAI', quote: 'ETH', side: 'BUY' } + expect(ensureCorrectSymbolCase(pair, supportTokens)).to.eql({ + base: 'DAI', quote: 'ETH', side: 'BUY' }) }) it('correct symbol in pair', function() { - let pair = { base: 'DAI', quote: 'Eth' } - expect(translateBaseQuote(pair, supportTokens)).to.eql({ - base: 'DAI', quote: 'ETH', + let pair: QueryInterface = { base: 'DAI', quote: 'Eth', side: 'BUY' } + expect(ensureCorrectSymbolCase(pair, supportTokens)).to.eql({ + base: 'DAI', quote: 'ETH', side: 'BUY' }) }) it('correct symbol case in pair', function() { - let pair = { base: 'IMBTC', quote: 'ETH' } - expect(translateBaseQuote(pair, supportTokens)).to.eql({ - base: 'imBTC', quote: 'ETH', + let pair: QueryInterface = { base: 'IMBTC', quote: 'ETH', side: 'BUY' } + expect(ensureCorrectSymbolCase(pair, supportTokens)).to.eql({ + base: 'imBTC', quote: 'ETH', side: 'BUY' }) }) }) From 6341145e16d2a7ec9e3d3cfccee1b374b6a20034 Mon Sep 17 00:00:00 2001 From: Kai Date: Mon, 22 Jun 2020 16:15:37 +0800 Subject: [PATCH 14/14] chore: add release task --- .gitignore | 1 + .npmignore | 13 +++++++++++++ package.json | 21 +++++++++++++-------- 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 .npmignore diff --git a/.gitignore b/.gitignore index 88b7762..2a6acb7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ yarn-error.log package-lock.json lib .env +*.tgz diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..25e31c5 --- /dev/null +++ b/.npmignore @@ -0,0 +1,13 @@ +# whitelist +!app/**/* +!lib/**/* +!package.json +!package-lock.json +!LICENSE +# blacklist +.* +node_modules +src +test +tsconfig.json + diff --git a/package.json b/package.json index 02c2e92..f265456 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,23 @@ { "name": "tokenlon-mmsk", "version": "0.6.2", - "description": "", + "description": "tokenlon market maker server kit", + "author": "imToken PTE. LTD.", + "license": "MIT", "main": "lib/index.js", "types": "src/globals.d.ts", + "homepage": "https://github.com/consenlabs/tokenlon-mmsk#readme", + "bugs": { + "url": "https://github.com/consenlabs/tokenlon-mmsk/issues" + }, "repository": { "type": "git", "url": "git+https://github.com/consenlabs/tokenlon-mmsk.git" }, - "author": "imToken PTE. LTD.", - "license": "MIT", + "files": [ + "app/**/*", + "lib/**/*" + ], "scripts": { "build": "run-s clean build:commonjs", "build:commonjs": "tsc", @@ -17,12 +25,9 @@ "clean": "rm -rf ./lib", "start": "node ./app/start.js", "test": "mocha --exit -r ts-node/register test/**/*.spec.ts", - "watch": "tsc -w" - }, - "bugs": { - "url": "https://github.com/consenlabs/tokenlon-mmsk/issues" + "watch": "tsc -w", + "release": "rm -f *.tgz{,.sha1sum.txt} && npm pack && sha1sum *.tgz > \"$(ls *.tgz | head -n 1).sha1sum.txt\"" }, - "homepage": "https://github.com/consenlabs/tokenlon-mmsk#readme", "devDependencies": { "@types/chai": "^4.2.11", "@types/mocha": "^7.0.2",