From a9a12d5fbc4697d83338279f6c95a9a9c92a742d Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 15:46:20 +0200 Subject: [PATCH 01/13] json-rpc: Fork from @iov/jsonrpc --- packages/json-rpc/.eslintignore | 1 + packages/json-rpc/.gitignore | 3 + packages/json-rpc/README.md | 12 + packages/json-rpc/jasmine-testrunner.js | 26 ++ packages/json-rpc/karma.conf.js | 56 +++ packages/json-rpc/nonces/1552895838 | 0 packages/json-rpc/nonces/1553085893 | 0 packages/json-rpc/nonces/1554721221 | 0 packages/json-rpc/nonces/1554724217 | 0 packages/json-rpc/nonces/1554737147 | 0 packages/json-rpc/nonces/1555314694 | 0 packages/json-rpc/nonces/1556008552 | 0 packages/json-rpc/nonces/1556028926 | 0 packages/json-rpc/nonces/1556095341 | 0 packages/json-rpc/nonces/1556616100 | 0 packages/json-rpc/nonces/1557811966 | 0 packages/json-rpc/nonces/1558346811 | 0 packages/json-rpc/nonces/1558456815 | 0 packages/json-rpc/nonces/1558460837 | 0 packages/json-rpc/nonces/1559802671 | 0 packages/json-rpc/nonces/1561970534 | 0 packages/json-rpc/nonces/1562080432 | 0 packages/json-rpc/nonces/1563468776 | 0 packages/json-rpc/nonces/1563887488 | 0 packages/json-rpc/nonces/1563960408 | 0 packages/json-rpc/nonces/1563981076 | 0 packages/json-rpc/nonces/1564503008 | 0 packages/json-rpc/nonces/1564651088 | 0 packages/json-rpc/nonces/1565101189 | 0 packages/json-rpc/nonces/1565595547 | 0 packages/json-rpc/nonces/1565876849 | 0 packages/json-rpc/nonces/1566487600 | 0 packages/json-rpc/nonces/1567435567 | 0 packages/json-rpc/nonces/1567608963 | 0 packages/json-rpc/nonces/1567694160 | 0 packages/json-rpc/nonces/1568039925 | 0 packages/json-rpc/nonces/1568116477 | 0 packages/json-rpc/nonces/1568786866 | 0 packages/json-rpc/nonces/1568910632 | 0 packages/json-rpc/nonces/1569319493 | 0 packages/json-rpc/nonces/1569487848 | 0 packages/json-rpc/nonces/1569929617 | 0 packages/json-rpc/nonces/1570527883 | 0 packages/json-rpc/nonces/1573026590 | 0 packages/json-rpc/nonces/1574869843 | 0 packages/json-rpc/nonces/1576569788 | 0 packages/json-rpc/nonces/1576595306 | 0 packages/json-rpc/nonces/1576678551 | 0 packages/json-rpc/nonces/1576746493 | 0 packages/json-rpc/nonces/1576760285 | 0 packages/json-rpc/nonces/1576767119 | 0 packages/json-rpc/nonces/1579019908 | 0 packages/json-rpc/nonces/1581606289 | 0 packages/json-rpc/nonces/1581681020 | 0 packages/json-rpc/nonces/1584038020 | 0 packages/json-rpc/nonces/1588011428 | 0 packages/json-rpc/nonces/1591293896 | 0 packages/json-rpc/nonces/README.txt | 1 + packages/json-rpc/package.json | 44 ++ packages/json-rpc/src/id.spec.ts | 21 + packages/json-rpc/src/id.ts | 13 + packages/json-rpc/src/index.ts | 20 + packages/json-rpc/src/jsonrpcclient.spec.ts | 88 ++++ packages/json-rpc/src/jsonrpcclient.ts | 37 ++ packages/json-rpc/src/parse.spec.ts | 429 ++++++++++++++++++ packages/json-rpc/src/parse.ts | 158 +++++++ packages/json-rpc/src/types.ts | 59 +++ .../src/workers/dummyservice.worker.ts | 68 +++ packages/json-rpc/tsconfig.json | 15 + packages/json-rpc/tsconfig.workers.json | 12 + packages/json-rpc/tslint.json | 3 + packages/json-rpc/typedoc.js | 14 + packages/json-rpc/types/id.d.ts | 8 + packages/json-rpc/types/index.d.ts | 20 + packages/json-rpc/types/jsonrpcclient.d.ts | 17 + packages/json-rpc/types/parse.d.ts | 23 + packages/json-rpc/types/types.d.ts | 46 ++ .../types/workers/dummyservice.worker.d.ts | 2 + packages/json-rpc/webpack.web.config.js | 28 ++ 79 files changed, 1224 insertions(+) create mode 120000 packages/json-rpc/.eslintignore create mode 100644 packages/json-rpc/.gitignore create mode 100644 packages/json-rpc/README.md create mode 100755 packages/json-rpc/jasmine-testrunner.js create mode 100644 packages/json-rpc/karma.conf.js create mode 100644 packages/json-rpc/nonces/1552895838 create mode 100644 packages/json-rpc/nonces/1553085893 create mode 100644 packages/json-rpc/nonces/1554721221 create mode 100644 packages/json-rpc/nonces/1554724217 create mode 100644 packages/json-rpc/nonces/1554737147 create mode 100644 packages/json-rpc/nonces/1555314694 create mode 100644 packages/json-rpc/nonces/1556008552 create mode 100644 packages/json-rpc/nonces/1556028926 create mode 100644 packages/json-rpc/nonces/1556095341 create mode 100644 packages/json-rpc/nonces/1556616100 create mode 100644 packages/json-rpc/nonces/1557811966 create mode 100644 packages/json-rpc/nonces/1558346811 create mode 100644 packages/json-rpc/nonces/1558456815 create mode 100644 packages/json-rpc/nonces/1558460837 create mode 100644 packages/json-rpc/nonces/1559802671 create mode 100644 packages/json-rpc/nonces/1561970534 create mode 100644 packages/json-rpc/nonces/1562080432 create mode 100644 packages/json-rpc/nonces/1563468776 create mode 100644 packages/json-rpc/nonces/1563887488 create mode 100644 packages/json-rpc/nonces/1563960408 create mode 100644 packages/json-rpc/nonces/1563981076 create mode 100644 packages/json-rpc/nonces/1564503008 create mode 100644 packages/json-rpc/nonces/1564651088 create mode 100644 packages/json-rpc/nonces/1565101189 create mode 100644 packages/json-rpc/nonces/1565595547 create mode 100644 packages/json-rpc/nonces/1565876849 create mode 100644 packages/json-rpc/nonces/1566487600 create mode 100644 packages/json-rpc/nonces/1567435567 create mode 100644 packages/json-rpc/nonces/1567608963 create mode 100644 packages/json-rpc/nonces/1567694160 create mode 100644 packages/json-rpc/nonces/1568039925 create mode 100644 packages/json-rpc/nonces/1568116477 create mode 100644 packages/json-rpc/nonces/1568786866 create mode 100644 packages/json-rpc/nonces/1568910632 create mode 100644 packages/json-rpc/nonces/1569319493 create mode 100644 packages/json-rpc/nonces/1569487848 create mode 100644 packages/json-rpc/nonces/1569929617 create mode 100644 packages/json-rpc/nonces/1570527883 create mode 100644 packages/json-rpc/nonces/1573026590 create mode 100644 packages/json-rpc/nonces/1574869843 create mode 100644 packages/json-rpc/nonces/1576569788 create mode 100644 packages/json-rpc/nonces/1576595306 create mode 100644 packages/json-rpc/nonces/1576678551 create mode 100644 packages/json-rpc/nonces/1576746493 create mode 100644 packages/json-rpc/nonces/1576760285 create mode 100644 packages/json-rpc/nonces/1576767119 create mode 100644 packages/json-rpc/nonces/1579019908 create mode 100644 packages/json-rpc/nonces/1581606289 create mode 100644 packages/json-rpc/nonces/1581681020 create mode 100644 packages/json-rpc/nonces/1584038020 create mode 100644 packages/json-rpc/nonces/1588011428 create mode 100644 packages/json-rpc/nonces/1591293896 create mode 100644 packages/json-rpc/nonces/README.txt create mode 100644 packages/json-rpc/package.json create mode 100644 packages/json-rpc/src/id.spec.ts create mode 100644 packages/json-rpc/src/id.ts create mode 100644 packages/json-rpc/src/index.ts create mode 100644 packages/json-rpc/src/jsonrpcclient.spec.ts create mode 100644 packages/json-rpc/src/jsonrpcclient.ts create mode 100644 packages/json-rpc/src/parse.spec.ts create mode 100644 packages/json-rpc/src/parse.ts create mode 100644 packages/json-rpc/src/types.ts create mode 100644 packages/json-rpc/src/workers/dummyservice.worker.ts create mode 100644 packages/json-rpc/tsconfig.json create mode 100644 packages/json-rpc/tsconfig.workers.json create mode 100644 packages/json-rpc/tslint.json create mode 100644 packages/json-rpc/typedoc.js create mode 100644 packages/json-rpc/types/id.d.ts create mode 100644 packages/json-rpc/types/index.d.ts create mode 100644 packages/json-rpc/types/jsonrpcclient.d.ts create mode 100644 packages/json-rpc/types/parse.d.ts create mode 100644 packages/json-rpc/types/types.d.ts create mode 100644 packages/json-rpc/types/workers/dummyservice.worker.d.ts create mode 100644 packages/json-rpc/webpack.web.config.js diff --git a/packages/json-rpc/.eslintignore b/packages/json-rpc/.eslintignore new file mode 120000 index 00000000..86039baf --- /dev/null +++ b/packages/json-rpc/.eslintignore @@ -0,0 +1 @@ +../../.eslintignore \ No newline at end of file diff --git a/packages/json-rpc/.gitignore b/packages/json-rpc/.gitignore new file mode 100644 index 00000000..68bf3735 --- /dev/null +++ b/packages/json-rpc/.gitignore @@ -0,0 +1,3 @@ +build/ +dist/ +docs/ diff --git a/packages/json-rpc/README.md b/packages/json-rpc/README.md new file mode 100644 index 00000000..63a28283 --- /dev/null +++ b/packages/json-rpc/README.md @@ -0,0 +1,12 @@ +# @iov/jsonrpc + +[![npm version](https://img.shields.io/npm/v/@iov/jsonrpc.svg)](https://www.npmjs.com/package/@iov/jsonrpc) + +This package provides a light framework for implementing a [JSON-RPC 2.0 API](https://www.jsonrpc.org/specification). + +## License + +This package is part of the IOV-Core repository, licensed under the Apache +License 2.0 (see +[NOTICE](https://github.com/iov-one/iov-core/blob/master/NOTICE) and +[LICENSE](https://github.com/iov-one/iov-core/blob/master/LICENSE)). diff --git a/packages/json-rpc/jasmine-testrunner.js b/packages/json-rpc/jasmine-testrunner.js new file mode 100755 index 00000000..9fada59b --- /dev/null +++ b/packages/json-rpc/jasmine-testrunner.js @@ -0,0 +1,26 @@ +#!/usr/bin/env node + +require("source-map-support").install(); +const defaultSpecReporterConfig = require("../../jasmine-spec-reporter.config.json"); + +// setup Jasmine +const Jasmine = require("jasmine"); +const jasmine = new Jasmine(); +jasmine.loadConfig({ + spec_dir: "build", + spec_files: ["**/*.spec.js"], + helpers: [], + random: false, + seed: null, + stopSpecOnExpectationFailure: false, +}); +jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 15 * 1000; + +// setup reporter +const { SpecReporter } = require("jasmine-spec-reporter"); +const reporter = new SpecReporter({ ...defaultSpecReporterConfig }); + +// initialize and execute +jasmine.env.clearReporters(); +jasmine.addReporter(reporter); +jasmine.execute(); diff --git a/packages/json-rpc/karma.conf.js b/packages/json-rpc/karma.conf.js new file mode 100644 index 00000000..cf250e2c --- /dev/null +++ b/packages/json-rpc/karma.conf.js @@ -0,0 +1,56 @@ +module.exports = function (config) { + config.set({ + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: ".", + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ["jasmine"], + + // list of files / patterns to load in the browser + files: [ + "dist/web/tests.js", + { + pattern: "dist/web/dummyservice.worker.js", + included: false, + served: true, + watched: false, + nocache: true, + }, + ], + + client: { + jasmine: { + random: false, + timeoutInterval: 15000, + }, + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ["progress", "kjhtml"], + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ["Firefox"], + + browserNoActivityTimeout: 30000, + + // Keep brower open for debugging. This is overridden by yarn scripts + singleRun: false, + }); +}; diff --git a/packages/json-rpc/nonces/1552895838 b/packages/json-rpc/nonces/1552895838 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1553085893 b/packages/json-rpc/nonces/1553085893 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1554721221 b/packages/json-rpc/nonces/1554721221 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1554724217 b/packages/json-rpc/nonces/1554724217 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1554737147 b/packages/json-rpc/nonces/1554737147 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1555314694 b/packages/json-rpc/nonces/1555314694 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1556008552 b/packages/json-rpc/nonces/1556008552 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1556028926 b/packages/json-rpc/nonces/1556028926 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1556095341 b/packages/json-rpc/nonces/1556095341 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1556616100 b/packages/json-rpc/nonces/1556616100 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1557811966 b/packages/json-rpc/nonces/1557811966 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1558346811 b/packages/json-rpc/nonces/1558346811 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1558456815 b/packages/json-rpc/nonces/1558456815 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1558460837 b/packages/json-rpc/nonces/1558460837 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1559802671 b/packages/json-rpc/nonces/1559802671 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1561970534 b/packages/json-rpc/nonces/1561970534 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1562080432 b/packages/json-rpc/nonces/1562080432 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1563468776 b/packages/json-rpc/nonces/1563468776 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1563887488 b/packages/json-rpc/nonces/1563887488 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1563960408 b/packages/json-rpc/nonces/1563960408 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1563981076 b/packages/json-rpc/nonces/1563981076 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1564503008 b/packages/json-rpc/nonces/1564503008 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1564651088 b/packages/json-rpc/nonces/1564651088 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1565101189 b/packages/json-rpc/nonces/1565101189 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1565595547 b/packages/json-rpc/nonces/1565595547 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1565876849 b/packages/json-rpc/nonces/1565876849 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1566487600 b/packages/json-rpc/nonces/1566487600 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1567435567 b/packages/json-rpc/nonces/1567435567 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1567608963 b/packages/json-rpc/nonces/1567608963 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1567694160 b/packages/json-rpc/nonces/1567694160 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1568039925 b/packages/json-rpc/nonces/1568039925 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1568116477 b/packages/json-rpc/nonces/1568116477 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1568786866 b/packages/json-rpc/nonces/1568786866 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1568910632 b/packages/json-rpc/nonces/1568910632 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1569319493 b/packages/json-rpc/nonces/1569319493 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1569487848 b/packages/json-rpc/nonces/1569487848 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1569929617 b/packages/json-rpc/nonces/1569929617 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1570527883 b/packages/json-rpc/nonces/1570527883 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1573026590 b/packages/json-rpc/nonces/1573026590 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1574869843 b/packages/json-rpc/nonces/1574869843 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1576569788 b/packages/json-rpc/nonces/1576569788 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1576595306 b/packages/json-rpc/nonces/1576595306 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1576678551 b/packages/json-rpc/nonces/1576678551 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1576746493 b/packages/json-rpc/nonces/1576746493 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1576760285 b/packages/json-rpc/nonces/1576760285 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1576767119 b/packages/json-rpc/nonces/1576767119 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1579019908 b/packages/json-rpc/nonces/1579019908 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1581606289 b/packages/json-rpc/nonces/1581606289 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1581681020 b/packages/json-rpc/nonces/1581681020 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1584038020 b/packages/json-rpc/nonces/1584038020 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1588011428 b/packages/json-rpc/nonces/1588011428 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/1591293896 b/packages/json-rpc/nonces/1591293896 new file mode 100644 index 00000000..e69de29b diff --git a/packages/json-rpc/nonces/README.txt b/packages/json-rpc/nonces/README.txt new file mode 100644 index 00000000..092fe732 --- /dev/null +++ b/packages/json-rpc/nonces/README.txt @@ -0,0 +1 @@ +Directory used to trigger lerna package updates for all packages diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json new file mode 100644 index 00000000..cf5caa2b --- /dev/null +++ b/packages/json-rpc/package.json @@ -0,0 +1,44 @@ +{ + "name": "@iov/jsonrpc", + "version": "2.5.0", + "description": "Framework for implementing a JSON-RPC 2.0 API", + "author": "IOV SAS ", + "license": "Apache-2.0", + "main": "build/index.js", + "types": "types/index.d.ts", + "files": [ + "build/", + "types/", + "*.md", + "!*.spec.*", + "!**/testdata/" + ], + "repository": { + "type": "git", + "url": "https://github.com/iov-one/iov-core/tree/master/packages/iov-jsonrpc" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "docs": "shx rm -rf docs && typedoc --options typedoc.js", + "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && tslint -t verbose --project .", + "format": "prettier --write --loglevel warn \"./src/**/*.ts\"", + "test-node": "node jasmine-testrunner.js", + "test-edge": "yarn pack-web && karma start --single-run --browsers Edge", + "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", + "test-chrome": "yarn pack-web && karma start --single-run --browsers ChromeHeadless", + "test-safari": "yarn pack-web && karma start --single-run --browsers Safari", + "test": "yarn build-or-skip && yarn test-node", + "move-types": "shx rm -r ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", + "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", + "build": "shx rm -rf ./build && tsc && tsc -p tsconfig.workers.json && yarn move-types && yarn format-types", + "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", + "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" + }, + "dependencies": { + "@iov/encoding": "^2.5.0", + "@iov/stream": "^2.3.2", + "xstream": "^11.10.0" + } +} diff --git a/packages/json-rpc/src/id.spec.ts b/packages/json-rpc/src/id.spec.ts new file mode 100644 index 00000000..7f5b51fb --- /dev/null +++ b/packages/json-rpc/src/id.spec.ts @@ -0,0 +1,21 @@ +import { makeJsonRpcId } from "./id"; + +describe("id", () => { + describe("makeJsonRpcId", () => { + it("returns a string or number", () => { + const id = makeJsonRpcId(); + expect(["string", "number"]).toContain(typeof id); + }); + + it("returns unique values", () => { + const ids = new Set([ + makeJsonRpcId(), + makeJsonRpcId(), + makeJsonRpcId(), + makeJsonRpcId(), + makeJsonRpcId(), + ]); + expect(ids.size).toEqual(5); + }); + }); +}); diff --git a/packages/json-rpc/src/id.ts b/packages/json-rpc/src/id.ts new file mode 100644 index 00000000..c205fa17 --- /dev/null +++ b/packages/json-rpc/src/id.ts @@ -0,0 +1,13 @@ +// Start with 10001 to avoid possible collisions with all hand-selected values like e.g. 1,2,3,42,100 +let counter = 10000; + +/** + * Creates a new ID to be used for creating a JSON-RPC request. + * + * Multiple calls of this produce unique values. + * + * The output may be any value compatible to JSON-RPC request IDs with an undefined output format and generation logic. + */ +export function makeJsonRpcId(): number { + return (counter += 1); +} diff --git a/packages/json-rpc/src/index.ts b/packages/json-rpc/src/index.ts new file mode 100644 index 00000000..fc6fa06a --- /dev/null +++ b/packages/json-rpc/src/index.ts @@ -0,0 +1,20 @@ +export { makeJsonRpcId } from "./id"; +export { JsonRpcClient, SimpleMessagingConnection } from "./jsonrpcclient"; +export { + parseJsonRpcId, + parseJsonRpcRequest, + parseJsonRpcResponse, + parseJsonRpcErrorResponse, + parseJsonRpcSuccessResponse, +} from "./parse"; +export { + isJsonRpcErrorResponse, + isJsonRpcSuccessResponse, + JsonRpcError, + JsonRpcErrorResponse, + JsonRpcId, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcSuccessResponse, + jsonRpcCode, +} from "./types"; diff --git a/packages/json-rpc/src/jsonrpcclient.spec.ts b/packages/json-rpc/src/jsonrpcclient.spec.ts new file mode 100644 index 00000000..2af43e90 --- /dev/null +++ b/packages/json-rpc/src/jsonrpcclient.spec.ts @@ -0,0 +1,88 @@ +/// + +import { Producer, Stream } from "xstream"; + +import { JsonRpcClient, SimpleMessagingConnection } from "./jsonrpcclient"; +import { parseJsonRpcResponse } from "./parse"; +import { JsonRpcRequest, JsonRpcResponse } from "./types"; + +function pendingWithoutWorker(): void { + if (typeof Worker === "undefined") { + pending("Environment without WebWorker support detected. Marked as pending."); + } +} + +function makeSimpleMessagingConnection( + worker: Worker, +): SimpleMessagingConnection { + const producer: Producer = { + start: (listener) => { + // tslint:disable-next-line:no-object-mutation + worker.onmessage = (event) => { + listener.next(parseJsonRpcResponse(event.data)); + }; + }, + stop: () => { + // tslint:disable-next-line:no-object-mutation + worker.onmessage = null; + }, + }; + + return { + responseStream: Stream.create(producer), + sendRequest: (request) => worker.postMessage(request), + }; +} + +describe("JsonRpcClient", () => { + const dummyserviceKarmaUrl = "/base/dist/web/dummyservice.worker.js"; + + it("can be constructed with a Worker", () => { + pendingWithoutWorker(); + + const worker = new Worker(dummyserviceKarmaUrl); + const client = new JsonRpcClient(makeSimpleMessagingConnection(worker)); + expect(client).toBeTruthy(); + worker.terminate(); + }); + + it("can communicate with worker", async () => { + pendingWithoutWorker(); + + const worker = new Worker(dummyserviceKarmaUrl); + + const client = new JsonRpcClient(makeSimpleMessagingConnection(worker)); + const response = await client.run({ + jsonrpc: "2.0", + id: 123, + method: "getIdentities", + params: ["Who are you?"], + }); + expect(response.jsonrpc).toEqual("2.0"); + expect(response.id).toEqual(123); + expect(response.result).toEqual(`Called getIdentities("Who are you?")`); + + worker.terminate(); + }); + + it("supports params as dictionary", async () => { + pendingWithoutWorker(); + + const worker = new Worker(dummyserviceKarmaUrl); + + const client = new JsonRpcClient(makeSimpleMessagingConnection(worker)); + const response = await client.run({ + jsonrpc: "2.0", + id: 123, + method: "getIdentities", + params: { + a: "Who are you?", + }, + }); + expect(response.jsonrpc).toEqual("2.0"); + expect(response.id).toEqual(123); + expect(response.result).toEqual(`Called getIdentities({"a":"Who are you?"})`); + + worker.terminate(); + }); +}); diff --git a/packages/json-rpc/src/jsonrpcclient.ts b/packages/json-rpc/src/jsonrpcclient.ts new file mode 100644 index 00000000..d2f60db6 --- /dev/null +++ b/packages/json-rpc/src/jsonrpcclient.ts @@ -0,0 +1,37 @@ +import { firstEvent } from "@iov/stream"; +import { Stream } from "xstream"; + +import { isJsonRpcErrorResponse, JsonRpcRequest, JsonRpcResponse, JsonRpcSuccessResponse } from "./types"; + +export interface SimpleMessagingConnection { + readonly responseStream: Stream; + readonly sendRequest: (request: Request) => void; +} + +/** + * A thin wrapper that is used to bring together requests and responses by ID. + * + * Using this class is only advised for continous communication channels like + * WebSockets or WebWorker messaging. + */ +export class JsonRpcClient { + private readonly connection: SimpleMessagingConnection; + + public constructor(connection: SimpleMessagingConnection) { + this.connection = connection; + } + + public async run(request: JsonRpcRequest): Promise { + const filteredStream = this.connection.responseStream.filter((r) => r.id === request.id); + const pendingResponses = firstEvent(filteredStream); + this.connection.sendRequest(request); + + const response = await pendingResponses; + if (isJsonRpcErrorResponse(response)) { + const error = response.error; + throw new Error(`JSON RPC error: code=${error.code}; message='${error.message}'`); + } + + return response; + } +} diff --git a/packages/json-rpc/src/parse.spec.ts b/packages/json-rpc/src/parse.spec.ts new file mode 100644 index 00000000..4d9c7227 --- /dev/null +++ b/packages/json-rpc/src/parse.spec.ts @@ -0,0 +1,429 @@ +import { + parseJsonRpcErrorResponse, + parseJsonRpcId, + parseJsonRpcResponse, + parseJsonRpcSuccessResponse, +} from "./parse"; +import { jsonRpcCode, JsonRpcErrorResponse, JsonRpcRequest, JsonRpcSuccessResponse } from "./types"; + +describe("parse", () => { + describe("parseJsonRpcId", () => { + it("works for number IDs", () => { + const request: JsonRpcRequest = { + jsonrpc: "2.0", + id: 123, + method: "foo", + params: {}, + }; + expect(parseJsonRpcId(request)).toEqual(123); + }); + + it("works for string IDs", () => { + const request: JsonRpcRequest = { + jsonrpc: "2.0", + id: "329fg3b", + method: "foo", + params: {}, + }; + expect(parseJsonRpcId(request)).toEqual("329fg3b"); + }); + + it("returns null for invaid IDs", () => { + // unset + { + const request = { + jsonrpc: "2.0", + method: "foo", + params: {}, + }; + expect(parseJsonRpcId(request)).toBeNull(); + } + // wrong type (object) + { + const request = { + jsonrpc: "2.0", + id: { content: 123 }, + method: "foo", + params: {}, + }; + expect(parseJsonRpcId(request)).toBeNull(); + } + // wrong type (Array) + { + const request = { + jsonrpc: "2.0", + id: [1, 2, 3], + method: "foo", + params: {}, + }; + expect(parseJsonRpcId(request)).toBeNull(); + } + // wrong type (null) + { + const request = { + jsonrpc: "2.0", + id: null, + method: "foo", + params: {}, + }; + expect(parseJsonRpcId(request)).toBeNull(); + } + }); + }); + + describe("parseJsonRpcErrorResponse", () => { + it("works for valid error", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + data: [2, 3, 4], + }, + }; + expect(parseJsonRpcErrorResponse(response)).toEqual(response); + }); + + it("works for error with string ID", () => { + const response: any = { + jsonrpc: "2.0", + id: "a3g4g34g", + error: { + code: jsonRpcCode.parseError, + message: "Could not parse request ID", + }, + }; + expect(parseJsonRpcErrorResponse(response)).toEqual(response); + }); + + it("works for error with null ID", () => { + const response: any = { + jsonrpc: "2.0", + id: null, + error: { + code: jsonRpcCode.parseError, + message: "Could not parse request ID", + }, + }; + expect(parseJsonRpcErrorResponse(response)).toEqual(response); + }); + + it("works for error with null data", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + data: null, + }, + }; + expect(parseJsonRpcErrorResponse(response)).toEqual(response); + }); + + it("works for error with unset data", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(parseJsonRpcErrorResponse(response)).toEqual(response); + }); + + it("throws for invalid type", () => { + const expectedError = /data must be JSON compatible dictionary/i; + expect(() => parseJsonRpcErrorResponse(undefined)).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse(null)).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse(false)).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse("error")).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse(42)).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse(() => true)).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse({ foo: () => true })).toThrowError(expectedError); + expect(() => parseJsonRpcErrorResponse({ foo: () => new Uint8Array([]) })).toThrowError(expectedError); + }); + + it("throws for invalid version", () => { + // wrong type + { + const response: any = { + jsonrpc: 2.0, + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(() => parseJsonRpcErrorResponse(response)).toThrowError(/got unexpected jsonrpc version/i); + } + // wrong version + { + const response: any = { + jsonrpc: "1.0", + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(() => parseJsonRpcErrorResponse(response)).toThrowError(/got unexpected jsonrpc version/i); + } + // unset + { + const response: any = { + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(() => parseJsonRpcErrorResponse(response)).toThrowError(/got unexpected jsonrpc version/i); + } + }); + + it("throws for invalid ID", () => { + // wrong type + { + const response: any = { + jsonrpc: "2.0", + id: [1, 2, 3], + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(() => parseJsonRpcErrorResponse(response)).toThrowError(/invalid id field/i); + } + // unset + { + const response: any = { + jsonrpc: "2.0", + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(() => parseJsonRpcErrorResponse(response)).toThrowError(/invalid id field/i); + } + }); + + it("throws for success response", () => { + const response: JsonRpcSuccessResponse = { + jsonrpc: "2.0", + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcErrorResponse(response)).toThrowError(/invalid error field/i); + }); + }); + + describe("parseJsonRpcSuccessResponse", () => { + it("works for response with dict result", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + result: { + foo: "bar", + }, + }; + expect(parseJsonRpcSuccessResponse(response)).toEqual(response); + }); + + it("works for response with null result", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + result: null, + }; + expect(parseJsonRpcSuccessResponse(response)).toEqual(response); + }); + + it("works for response with number ID", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + result: {}, + }; + expect(parseJsonRpcSuccessResponse(response)).toEqual(response); + }); + + it("works for response with string ID", () => { + const response: any = { + jsonrpc: "2.0", + id: "40gfh408g", + result: {}, + }; + expect(parseJsonRpcSuccessResponse(response)).toEqual(response); + }); + + it("throws for invalid type", () => { + const expectedError = /data must be JSON compatible dictionary/i; + expect(() => parseJsonRpcSuccessResponse(undefined)).toThrowError(expectedError); + expect(() => parseJsonRpcSuccessResponse(null)).toThrowError(expectedError); + expect(() => parseJsonRpcSuccessResponse(false)).toThrowError(expectedError); + expect(() => parseJsonRpcSuccessResponse("success")).toThrowError(expectedError); + expect(() => parseJsonRpcSuccessResponse(42)).toThrowError(expectedError); + expect(() => parseJsonRpcSuccessResponse(() => true)).toThrowError(expectedError); + expect(() => parseJsonRpcSuccessResponse({ foo: () => true })).toThrowError(expectedError); + }); + + it("throws for invalid version", () => { + // wrong type + { + const response: any = { + jsonrpc: 2.0, + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/got unexpected jsonrpc version/i); + } + // wrong version + { + const response: any = { + jsonrpc: "1.0", + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/got unexpected jsonrpc version/i); + } + // unset + { + const response: any = { + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/got unexpected jsonrpc version/i); + } + }); + + it("throws for invalid ID", () => { + // wrong type + { + const response: any = { + jsonrpc: "2.0", + id: [1, 2, 3], + result: 3000, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/invalid id field/i); + } + // wrong type + { + const response: any = { + jsonrpc: "2.0", + id: null, + result: 3000, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/invalid id field/i); + } + // unset + { + const response: any = { + jsonrpc: "2.0", + result: 3000, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/invalid id field/i); + } + }); + + it("throws for error response", () => { + const response: JsonRpcErrorResponse = { + jsonrpc: "2.0", + id: 123, + error: { + code: jsonRpcCode.parseError, + message: "Could not parse request ID", + }, + }; + expect(() => parseJsonRpcSuccessResponse(response)).toThrowError(/invalid result field/i); + }); + }); + + describe("parseJsonRpcResponse", () => { + it("works for success response", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + result: 3000, + }; + expect(parseJsonRpcResponse(response)).toEqual(response); + }); + + it("works for error response", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + data: [2, 3, 4], + }, + }; + expect(parseJsonRpcResponse(response)).toEqual(response); + }); + + it("favours error if response is error and success at the same time", () => { + const response: any = { + jsonrpc: "2.0", + id: 123, + result: 3000, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }; + expect(parseJsonRpcResponse(response)).toEqual({ + jsonrpc: "2.0", + id: 123, + error: { + code: jsonRpcCode.serverError.default, + message: "Something bad happened", + }, + }); + }); + + it("throws for invalid type", () => { + const expectedError = /data must be JSON compatible dictionary/i; + expect(() => parseJsonRpcResponse(undefined)).toThrowError(expectedError); + expect(() => parseJsonRpcResponse(null)).toThrowError(expectedError); + expect(() => parseJsonRpcResponse(false)).toThrowError(expectedError); + expect(() => parseJsonRpcResponse("error")).toThrowError(expectedError); + expect(() => parseJsonRpcResponse(42)).toThrowError(expectedError); + expect(() => parseJsonRpcResponse(() => true)).toThrowError(expectedError); + expect(() => parseJsonRpcResponse({ foo: () => true })).toThrowError(expectedError); + expect(() => parseJsonRpcResponse({ foo: () => new Uint8Array([]) })).toThrowError(expectedError); + }); + + it("throws for invalid version", () => { + const expectedError = /got unexpected jsonrpc version/i; + // wrong type + { + const response: any = { + jsonrpc: 2.0, + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcResponse(response)).toThrowError(expectedError); + } + // wrong version + { + const response: any = { + jsonrpc: "1.0", + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcResponse(response)).toThrowError(expectedError); + } + // unset + { + const response: any = { + id: 123, + result: 3000, + }; + expect(() => parseJsonRpcResponse(response)).toThrowError(expectedError); + } + }); + }); +}); diff --git a/packages/json-rpc/src/parse.ts b/packages/json-rpc/src/parse.ts new file mode 100644 index 00000000..f1e103ee --- /dev/null +++ b/packages/json-rpc/src/parse.ts @@ -0,0 +1,158 @@ +import { + isJsonCompatibleArray, + isJsonCompatibleDictionary, + isJsonCompatibleValue, + JsonCompatibleDictionary, + JsonCompatibleValue, +} from "@iov/encoding"; + +import { + JsonRpcError, + JsonRpcErrorResponse, + JsonRpcId, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcSuccessResponse, +} from "./types"; + +/** + * Extracts ID field from request or response object. + * + * Returns `null` when no valid ID was found. + */ +export function parseJsonRpcId(data: unknown): JsonRpcId | null { + if (!isJsonCompatibleDictionary(data)) { + throw new Error("Data must be JSON compatible dictionary"); + } + + const id = data.id; + if (typeof id !== "number" && typeof id !== "string") { + return null; + } + return id; +} + +export function parseJsonRpcRequest(data: unknown): JsonRpcRequest { + if (!isJsonCompatibleDictionary(data)) { + throw new Error("Data must be JSON compatible dictionary"); + } + + if (data.jsonrpc !== "2.0") { + throw new Error(`Got unexpected jsonrpc version: ${data.jsonrpc}`); + } + + const id = parseJsonRpcId(data); + if (id === null) { + throw new Error("Invalid id field"); + } + + const method = data.method; + if (typeof method !== "string") { + throw new Error("Invalid method field"); + } + + if (!isJsonCompatibleArray(data.params) && !isJsonCompatibleDictionary(data.params)) { + throw new Error("Invalid params field"); + } + + return { + jsonrpc: "2.0", + id: id, + method: method, + params: data.params, + }; +} + +function parseError(error: JsonCompatibleDictionary): JsonRpcError { + if (typeof error.code !== "number") { + throw new Error("Error property 'code' is not a number"); + } + + if (typeof error.message !== "string") { + throw new Error("Error property 'message' is not a string"); + } + + let maybeUndefinedData: JsonCompatibleValue | undefined; + + if (error.data === undefined) { + maybeUndefinedData = undefined; + } else if (isJsonCompatibleValue(error.data)) { + maybeUndefinedData = error.data; + } else { + throw new Error("Error property 'data' is defined but not a JSON compatible value."); + } + + return { + code: error.code, + message: error.message, + ...(maybeUndefinedData !== undefined ? { data: maybeUndefinedData } : {}), + }; +} + +/** Throws if data is not a JsonRpcErrorResponse */ +export function parseJsonRpcErrorResponse(data: unknown): JsonRpcErrorResponse { + if (!isJsonCompatibleDictionary(data)) { + throw new Error("Data must be JSON compatible dictionary"); + } + + if (data.jsonrpc !== "2.0") { + throw new Error(`Got unexpected jsonrpc version: ${JSON.stringify(data)}`); + } + + const id = data.id; + if (typeof id !== "number" && typeof id !== "string" && id !== null) { + throw new Error("Invalid id field"); + } + + if (typeof data.error === "undefined" || !isJsonCompatibleDictionary(data.error)) { + throw new Error("Invalid error field"); + } + + return { + jsonrpc: "2.0", + id: id, + error: parseError(data.error), + }; +} + +/** Throws if data is not a JsonRpcSuccessResponse */ +export function parseJsonRpcSuccessResponse(data: unknown): JsonRpcSuccessResponse { + if (!isJsonCompatibleDictionary(data)) { + throw new Error("Data must be JSON compatible dictionary"); + } + + if (data.jsonrpc !== "2.0") { + throw new Error(`Got unexpected jsonrpc version: ${JSON.stringify(data)}`); + } + + const id = data.id; + if (typeof id !== "number" && typeof id !== "string") { + throw new Error("Invalid id field"); + } + + if (typeof data.result === "undefined") { + throw new Error("Invalid result field"); + } + + const result = data.result; + + return { + jsonrpc: "2.0", + id: id, + result: result, + }; +} + +/** + * Returns a JsonRpcErrorResponse if input can be parsed as a JSON-RPC error. Otherwise parses + * input as JsonRpcSuccessResponse. Throws if input is neither a valid error nor success response. + */ +export function parseJsonRpcResponse(data: unknown): JsonRpcResponse { + let response: JsonRpcResponse; + try { + response = parseJsonRpcErrorResponse(data); + } catch (_) { + response = parseJsonRpcSuccessResponse(data); + } + return response; +} diff --git a/packages/json-rpc/src/types.ts b/packages/json-rpc/src/types.ts new file mode 100644 index 00000000..2cfbf76a --- /dev/null +++ b/packages/json-rpc/src/types.ts @@ -0,0 +1,59 @@ +import { JsonCompatibleArray, JsonCompatibleDictionary, JsonCompatibleValue } from "@iov/encoding"; + +export type JsonRpcId = number | string; + +export interface JsonRpcRequest { + readonly jsonrpc: "2.0"; + readonly id: JsonRpcId; + readonly method: string; + readonly params: JsonCompatibleArray | JsonCompatibleDictionary; +} + +export interface JsonRpcSuccessResponse { + readonly jsonrpc: "2.0"; + readonly id: JsonRpcId; + readonly result: any; +} + +export interface JsonRpcError { + readonly code: number; + readonly message: string; + readonly data?: JsonCompatibleValue; +} + +/** + * And error object as described in https://www.jsonrpc.org/specification#error_object + */ +export interface JsonRpcErrorResponse { + readonly jsonrpc: "2.0"; + readonly id: JsonRpcId | null; + readonly error: JsonRpcError; +} + +export type JsonRpcResponse = JsonRpcSuccessResponse | JsonRpcErrorResponse; + +export function isJsonRpcErrorResponse(response: JsonRpcResponse): response is JsonRpcErrorResponse { + return typeof (response as JsonRpcErrorResponse).error === "object"; +} + +export function isJsonRpcSuccessResponse(response: JsonRpcResponse): response is JsonRpcSuccessResponse { + return !isJsonRpcErrorResponse(response); +} + +/** + * Error codes as specified in JSON-RPC 2.0 + * + * @see https://www.jsonrpc.org/specification#error_object + */ +export const jsonRpcCode = { + parseError: -32700, + invalidRequest: -32600, + methodNotFound: -32601, + invalidParams: -32602, + internalError: -32603, + // server error (Reserved for implementation-defined server-errors.): + // -32000 to -32099 + serverError: { + default: -32000, + }, +}; diff --git a/packages/json-rpc/src/workers/dummyservice.worker.ts b/packages/json-rpc/src/workers/dummyservice.worker.ts new file mode 100644 index 00000000..426e9803 --- /dev/null +++ b/packages/json-rpc/src/workers/dummyservice.worker.ts @@ -0,0 +1,68 @@ +/// + +// for testing only + +import { isJsonCompatibleDictionary } from "@iov/encoding"; + +import { parseJsonRpcId, parseJsonRpcRequest } from "../parse"; +import { + jsonRpcCode, + JsonRpcErrorResponse, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcSuccessResponse, +} from "../types"; + +function handleRequest(event: MessageEvent): JsonRpcResponse { + let request: JsonRpcRequest; + try { + request = parseJsonRpcRequest(event.data); + } catch (error) { + const requestId = parseJsonRpcId(event.data); + const errorResponse: JsonRpcErrorResponse = { + jsonrpc: "2.0", + id: requestId, + error: { + code: jsonRpcCode.invalidRequest, + message: error.toString(), + }, + }; + return errorResponse; + } + + let paramsString: string; + if (isJsonCompatibleDictionary(request.params)) { + paramsString = JSON.stringify(request.params); + } else { + paramsString = request.params + .map((p) => { + if (typeof p === "number") { + return p; + } else if (p === null) { + return `null`; + } else if (typeof p === "string") { + return `"${p}"`; + } else { + return p.toString(); + } + }) + .join(", "); + } + + const response: JsonRpcSuccessResponse = { + jsonrpc: "2.0", + id: request.id, + result: `Called ${request.method}(${paramsString})`, + }; + return response; +} + +onmessage = (event) => { + // filter out empty {"isTrusted":true} events + if (!event.data) { + return; + } + + const response = handleRequest(event); + setTimeout(() => postMessage(response), 50); +}; diff --git a/packages/json-rpc/tsconfig.json b/packages/json-rpc/tsconfig.json new file mode 100644 index 00000000..84e9390f --- /dev/null +++ b/packages/json-rpc/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "declarationDir": "build/types", + "rootDir": "src" + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "src/workers/**/*" + ] +} diff --git a/packages/json-rpc/tsconfig.workers.json b/packages/json-rpc/tsconfig.workers.json new file mode 100644 index 00000000..3801d574 --- /dev/null +++ b/packages/json-rpc/tsconfig.workers.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "declarationDir": "build/types", + "rootDir": "src" + }, + "include": [ + "src/workers/**/*" + ] +} diff --git a/packages/json-rpc/tslint.json b/packages/json-rpc/tslint.json new file mode 100644 index 00000000..0946f209 --- /dev/null +++ b/packages/json-rpc/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tslint.json" +} diff --git a/packages/json-rpc/typedoc.js b/packages/json-rpc/typedoc.js new file mode 100644 index 00000000..e2387c7d --- /dev/null +++ b/packages/json-rpc/typedoc.js @@ -0,0 +1,14 @@ +const packageJson = require("./package.json"); + +module.exports = { + src: ["./src"], + out: "docs", + exclude: "**/*.spec.ts", + target: "es6", + name: `${packageJson.name} Documentation`, + readme: "README.md", + mode: "file", + excludeExternals: true, + excludeNotExported: true, + excludePrivate: true, +}; diff --git a/packages/json-rpc/types/id.d.ts b/packages/json-rpc/types/id.d.ts new file mode 100644 index 00000000..ab69ffdf --- /dev/null +++ b/packages/json-rpc/types/id.d.ts @@ -0,0 +1,8 @@ +/** + * Creates a new ID to be used for creating a JSON-RPC request. + * + * Multiple calls of this produce unique values. + * + * The output may be any value compatible to JSON-RPC request IDs with an undefined output format and generation logic. + */ +export declare function makeJsonRpcId(): number; diff --git a/packages/json-rpc/types/index.d.ts b/packages/json-rpc/types/index.d.ts new file mode 100644 index 00000000..fc6fa06a --- /dev/null +++ b/packages/json-rpc/types/index.d.ts @@ -0,0 +1,20 @@ +export { makeJsonRpcId } from "./id"; +export { JsonRpcClient, SimpleMessagingConnection } from "./jsonrpcclient"; +export { + parseJsonRpcId, + parseJsonRpcRequest, + parseJsonRpcResponse, + parseJsonRpcErrorResponse, + parseJsonRpcSuccessResponse, +} from "./parse"; +export { + isJsonRpcErrorResponse, + isJsonRpcSuccessResponse, + JsonRpcError, + JsonRpcErrorResponse, + JsonRpcId, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcSuccessResponse, + jsonRpcCode, +} from "./types"; diff --git a/packages/json-rpc/types/jsonrpcclient.d.ts b/packages/json-rpc/types/jsonrpcclient.d.ts new file mode 100644 index 00000000..06199739 --- /dev/null +++ b/packages/json-rpc/types/jsonrpcclient.d.ts @@ -0,0 +1,17 @@ +import { Stream } from "xstream"; +import { JsonRpcRequest, JsonRpcResponse, JsonRpcSuccessResponse } from "./types"; +export interface SimpleMessagingConnection { + readonly responseStream: Stream; + readonly sendRequest: (request: Request) => void; +} +/** + * A thin wrapper that is used to bring together requests and responses by ID. + * + * Using this class is only advised for continous communication channels like + * WebSockets or WebWorker messaging. + */ +export declare class JsonRpcClient { + private readonly connection; + constructor(connection: SimpleMessagingConnection); + run(request: JsonRpcRequest): Promise; +} diff --git a/packages/json-rpc/types/parse.d.ts b/packages/json-rpc/types/parse.d.ts new file mode 100644 index 00000000..94576d99 --- /dev/null +++ b/packages/json-rpc/types/parse.d.ts @@ -0,0 +1,23 @@ +import { + JsonRpcErrorResponse, + JsonRpcId, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcSuccessResponse, +} from "./types"; +/** + * Extracts ID field from request or response object. + * + * Returns `null` when no valid ID was found. + */ +export declare function parseJsonRpcId(data: unknown): JsonRpcId | null; +export declare function parseJsonRpcRequest(data: unknown): JsonRpcRequest; +/** Throws if data is not a JsonRpcErrorResponse */ +export declare function parseJsonRpcErrorResponse(data: unknown): JsonRpcErrorResponse; +/** Throws if data is not a JsonRpcSuccessResponse */ +export declare function parseJsonRpcSuccessResponse(data: unknown): JsonRpcSuccessResponse; +/** + * Returns a JsonRpcErrorResponse if input can be parsed as a JSON-RPC error. Otherwise parses + * input as JsonRpcSuccessResponse. Throws if input is neither a valid error nor success response. + */ +export declare function parseJsonRpcResponse(data: unknown): JsonRpcResponse; diff --git a/packages/json-rpc/types/types.d.ts b/packages/json-rpc/types/types.d.ts new file mode 100644 index 00000000..6a85ad93 --- /dev/null +++ b/packages/json-rpc/types/types.d.ts @@ -0,0 +1,46 @@ +import { JsonCompatibleArray, JsonCompatibleDictionary, JsonCompatibleValue } from "@iov/encoding"; +export declare type JsonRpcId = number | string; +export interface JsonRpcRequest { + readonly jsonrpc: "2.0"; + readonly id: JsonRpcId; + readonly method: string; + readonly params: JsonCompatibleArray | JsonCompatibleDictionary; +} +export interface JsonRpcSuccessResponse { + readonly jsonrpc: "2.0"; + readonly id: JsonRpcId; + readonly result: any; +} +export interface JsonRpcError { + readonly code: number; + readonly message: string; + readonly data?: JsonCompatibleValue; +} +/** + * And error object as described in https://www.jsonrpc.org/specification#error_object + */ +export interface JsonRpcErrorResponse { + readonly jsonrpc: "2.0"; + readonly id: JsonRpcId | null; + readonly error: JsonRpcError; +} +export declare type JsonRpcResponse = JsonRpcSuccessResponse | JsonRpcErrorResponse; +export declare function isJsonRpcErrorResponse(response: JsonRpcResponse): response is JsonRpcErrorResponse; +export declare function isJsonRpcSuccessResponse( + response: JsonRpcResponse, +): response is JsonRpcSuccessResponse; +/** + * Error codes as specified in JSON-RPC 2.0 + * + * @see https://www.jsonrpc.org/specification#error_object + */ +export declare const jsonRpcCode: { + parseError: number; + invalidRequest: number; + methodNotFound: number; + invalidParams: number; + internalError: number; + serverError: { + default: number; + }; +}; diff --git a/packages/json-rpc/types/workers/dummyservice.worker.d.ts b/packages/json-rpc/types/workers/dummyservice.worker.d.ts new file mode 100644 index 00000000..67dd33d6 --- /dev/null +++ b/packages/json-rpc/types/workers/dummyservice.worker.d.ts @@ -0,0 +1,2 @@ +/// +export {}; diff --git a/packages/json-rpc/webpack.web.config.js b/packages/json-rpc/webpack.web.config.js new file mode 100644 index 00000000..fe7833f4 --- /dev/null +++ b/packages/json-rpc/webpack.web.config.js @@ -0,0 +1,28 @@ +const glob = require("glob"); +const path = require("path"); +const webpack = require("webpack"); + +const target = "web"; +const distdir = path.join(__dirname, "dist", "web"); + +module.exports = [ + { + // bundle for WebWorker tests + target: target, + entry: "./build/workers/dummyservice.worker.js", + output: { + path: distdir, + filename: "dummyservice.worker.js", + }, + }, + { + // bundle used for Karma tests + target: target, + entry: glob.sync("./build/**/*.spec.js"), + output: { + path: distdir, + filename: "tests.js", + }, + plugins: [new webpack.EnvironmentPlugin([])], + }, +]; From d141924b0208abb79d45f29de10e0107607d2d34 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 15:48:11 +0200 Subject: [PATCH 02/13] json-rpc: Update package.json --- packages/json-rpc/package.json | 15 ++++++++++----- yarn.lock | 10 ++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json index cf5caa2b..e395d122 100644 --- a/packages/json-rpc/package.json +++ b/packages/json-rpc/package.json @@ -1,8 +1,12 @@ { - "name": "@iov/jsonrpc", - "version": "2.5.0", + "name": "@cosmjs/json-rpc", + "version": "0.20.0", "description": "Framework for implementing a JSON-RPC 2.0 API", - "author": "IOV SAS ", + "contributors": [ + "IOV SAS ", + "Confio UO ", + "Will Clark " + ], "license": "Apache-2.0", "main": "build/index.js", "types": "types/index.d.ts", @@ -15,14 +19,15 @@ ], "repository": { "type": "git", - "url": "https://github.com/iov-one/iov-core/tree/master/packages/iov-jsonrpc" + "url": "https://github.com/CosmWasm/cosmjs/tree/master/packages/json-rpc" }, "publishConfig": { "access": "public" }, "scripts": { "docs": "shx rm -rf docs && typedoc --options typedoc.js", - "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && tslint -t verbose --project .", + "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", + "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "format": "prettier --write --loglevel warn \"./src/**/*.ts\"", "test-node": "node jasmine-testrunner.js", "test-edge": "yarn pack-web && karma start --single-run --browsers Edge", diff --git a/yarn.lock b/yarn.lock index 02e874ef..da1067d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -102,6 +102,16 @@ bn.js "^4.11.8" readonly-date "^1.0.0" +"@iov/encoding@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@iov/encoding/-/encoding-2.5.0.tgz#9612e529f45e63633b2375c13db28b9330ce6293" + integrity sha512-HGHLlQEvD23rFjW5PQrxD2B/6LiBHVSxqX6gjOz9KfcmIMIftRA0qROrTITfjjjUr/yZZEeNk4qjuBls9TaYcA== + dependencies: + "@cosmjs/encoding" "^0.20.0" + "@cosmjs/math" "^0.20.0" + "@cosmjs/utils" "^0.20.0" + readonly-date "^1.0.0" + "@iov/jsonrpc@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@iov/jsonrpc/-/jsonrpc-2.3.2.tgz#5cdfa56333741073cc00f17d54efb9f526b9705a" From 254faa935eb0122367420abc2ba37726d7319385 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 15:50:03 +0200 Subject: [PATCH 03/13] json-rpc: Remove tslint --- packages/json-rpc/src/jsonrpcclient.spec.ts | 2 -- packages/json-rpc/tslint.json | 3 --- 2 files changed, 5 deletions(-) delete mode 100644 packages/json-rpc/tslint.json diff --git a/packages/json-rpc/src/jsonrpcclient.spec.ts b/packages/json-rpc/src/jsonrpcclient.spec.ts index 2af43e90..a14cc3f2 100644 --- a/packages/json-rpc/src/jsonrpcclient.spec.ts +++ b/packages/json-rpc/src/jsonrpcclient.spec.ts @@ -17,13 +17,11 @@ function makeSimpleMessagingConnection( ): SimpleMessagingConnection { const producer: Producer = { start: (listener) => { - // tslint:disable-next-line:no-object-mutation worker.onmessage = (event) => { listener.next(parseJsonRpcResponse(event.data)); }; }, stop: () => { - // tslint:disable-next-line:no-object-mutation worker.onmessage = null; }, }; diff --git a/packages/json-rpc/tslint.json b/packages/json-rpc/tslint.json deleted file mode 100644 index 0946f209..00000000 --- a/packages/json-rpc/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tslint.json" -} From 5fa013cc925748a36e4e4b92caa45ccc64d46dc4 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 15:51:59 +0200 Subject: [PATCH 04/13] json-rpc: Remove @iov/encoding dependency --- packages/json-rpc/package.json | 1 - yarn.lock | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json index e395d122..1b561fb7 100644 --- a/packages/json-rpc/package.json +++ b/packages/json-rpc/package.json @@ -42,7 +42,6 @@ "pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js" }, "dependencies": { - "@iov/encoding": "^2.5.0", "@iov/stream": "^2.3.2", "xstream": "^11.10.0" } diff --git a/yarn.lock b/yarn.lock index da1067d0..02e874ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -102,16 +102,6 @@ bn.js "^4.11.8" readonly-date "^1.0.0" -"@iov/encoding@^2.5.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@iov/encoding/-/encoding-2.5.0.tgz#9612e529f45e63633b2375c13db28b9330ce6293" - integrity sha512-HGHLlQEvD23rFjW5PQrxD2B/6LiBHVSxqX6gjOz9KfcmIMIftRA0qROrTITfjjjUr/yZZEeNk4qjuBls9TaYcA== - dependencies: - "@cosmjs/encoding" "^0.20.0" - "@cosmjs/math" "^0.20.0" - "@cosmjs/utils" "^0.20.0" - readonly-date "^1.0.0" - "@iov/jsonrpc@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@iov/jsonrpc/-/jsonrpc-2.3.2.tgz#5cdfa56333741073cc00f17d54efb9f526b9705a" From 685fc54066f704a157877dd29e3748b042dd09b3 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:02:38 +0200 Subject: [PATCH 05/13] json-rpc: Fork JSON compatibility code from @iov/encoding --- packages/json-rpc/src/compatibility.spec.ts | 125 ++++++++++++++++++++ packages/json-rpc/src/compatibility.ts | 73 ++++++++++++ packages/json-rpc/types/compatibility.d.ts | 23 ++++ 3 files changed, 221 insertions(+) create mode 100644 packages/json-rpc/src/compatibility.spec.ts create mode 100644 packages/json-rpc/src/compatibility.ts create mode 100644 packages/json-rpc/types/compatibility.d.ts diff --git a/packages/json-rpc/src/compatibility.spec.ts b/packages/json-rpc/src/compatibility.spec.ts new file mode 100644 index 00000000..485fc784 --- /dev/null +++ b/packages/json-rpc/src/compatibility.spec.ts @@ -0,0 +1,125 @@ +import { isJsonCompatibleArray, isJsonCompatibleDictionary, isJsonCompatibleValue } from "./compatibility"; + +describe("json", () => { + function sum(a: number, b: number): number { + return a + b; + } + + describe("isJsonCompatibleValue", () => { + it("returns true for primitive types", () => { + expect(isJsonCompatibleValue(null)).toEqual(true); + expect(isJsonCompatibleValue(0)).toEqual(true); + expect(isJsonCompatibleValue(1)).toEqual(true); + expect(isJsonCompatibleValue("abc")).toEqual(true); + expect(isJsonCompatibleValue(true)).toEqual(true); + expect(isJsonCompatibleValue(false)).toEqual(true); + }); + + it("returns true for arrays", () => { + expect(isJsonCompatibleValue([1, 2, 3])).toEqual(true); + expect(isJsonCompatibleValue([1, "2", true, null])).toEqual(true); + expect(isJsonCompatibleValue([1, "2", true, null, [1, "2", true, null]])).toEqual(true); + expect(isJsonCompatibleValue([{ a: 123 }])).toEqual(true); + }); + + it("returns true for simple dicts", () => { + expect(isJsonCompatibleValue({ a: 123 })).toEqual(true); + expect(isJsonCompatibleValue({ a: "abc" })).toEqual(true); + expect(isJsonCompatibleValue({ a: true })).toEqual(true); + expect(isJsonCompatibleValue({ a: null })).toEqual(true); + }); + + it("returns true for dict with array", () => { + expect(isJsonCompatibleValue({ a: [1, 2, 3] })).toEqual(true); + expect(isJsonCompatibleValue({ a: [1, "2", true, null] })).toEqual(true); + }); + + it("returns true for nested dicts", () => { + expect(isJsonCompatibleValue({ a: { b: 123 } })).toEqual(true); + }); + + it("returns false for functions", () => { + expect(isJsonCompatibleValue(sum)).toEqual(false); + }); + + it("returns true for empty dicts", () => { + expect(isJsonCompatibleValue({})).toEqual(true); + }); + }); + + describe("isJsonCompatibleArray", () => { + it("returns false for primitive types", () => { + expect(isJsonCompatibleArray(null)).toEqual(false); + expect(isJsonCompatibleArray(undefined)).toEqual(false); + expect(isJsonCompatibleArray(0)).toEqual(false); + expect(isJsonCompatibleArray(1)).toEqual(false); + expect(isJsonCompatibleArray("abc")).toEqual(false); + expect(isJsonCompatibleArray(true)).toEqual(false); + expect(isJsonCompatibleArray(false)).toEqual(false); + }); + + it("returns true for arrays", () => { + expect(isJsonCompatibleArray([1, 2, 3])).toEqual(true); + expect(isJsonCompatibleArray([1, "2", true, null])).toEqual(true); + expect(isJsonCompatibleArray([1, "2", true, null, [1, "2", true, null]])).toEqual(true); + expect(isJsonCompatibleArray([{ a: 123 }])).toEqual(true); + }); + + it("returns false for dicts", () => { + expect(isJsonCompatibleArray({ a: 123 })).toEqual(false); + expect(isJsonCompatibleArray({ a: "abc" })).toEqual(false); + expect(isJsonCompatibleArray({ a: true })).toEqual(false); + expect(isJsonCompatibleArray({ a: null })).toEqual(false); + }); + + it("returns false for functions", () => { + expect(isJsonCompatibleArray(sum)).toEqual(false); + }); + }); + + describe("isJsonCompatibleDictionary", () => { + it("returns false for primitive types", () => { + expect(isJsonCompatibleDictionary(null)).toEqual(false); + expect(isJsonCompatibleDictionary(undefined)).toEqual(false); + expect(isJsonCompatibleDictionary(0)).toEqual(false); + expect(isJsonCompatibleDictionary(1)).toEqual(false); + expect(isJsonCompatibleDictionary("abc")).toEqual(false); + expect(isJsonCompatibleDictionary(true)).toEqual(false); + expect(isJsonCompatibleDictionary(false)).toEqual(false); + }); + + it("returns false for other objects", () => { + expect(isJsonCompatibleDictionary(new Uint8Array([0x00]))).toEqual(false); + expect(isJsonCompatibleDictionary(/123/)).toEqual(false); + expect(isJsonCompatibleDictionary(new Date())).toEqual(false); + }); + + it("returns false for arrays", () => { + expect(isJsonCompatibleDictionary([1, 2, 3])).toEqual(false); + }); + + it("returns false for functions", () => { + expect(isJsonCompatibleDictionary(sum)).toEqual(false); + }); + + it("returns true for empty dicts", () => { + expect(isJsonCompatibleDictionary({})).toEqual(true); + }); + + it("returns true for simple dicts", () => { + expect(isJsonCompatibleDictionary({ a: 123 })).toEqual(true); + expect(isJsonCompatibleDictionary({ a: "abc" })).toEqual(true); + expect(isJsonCompatibleDictionary({ a: true })).toEqual(true); + expect(isJsonCompatibleDictionary({ a: null })).toEqual(true); + }); + + it("returns true for dict with array", () => { + expect(isJsonCompatibleDictionary({ a: [1, 2, 3] })).toEqual(true); + expect(isJsonCompatibleDictionary({ a: [1, "2", true, null] })).toEqual(true); + }); + + it("returns true for nested dicts", () => { + expect(isJsonCompatibleDictionary({ a: { b: 123 } })).toEqual(true); + }); + }); +}); diff --git a/packages/json-rpc/src/compatibility.ts b/packages/json-rpc/src/compatibility.ts new file mode 100644 index 00000000..0906f384 --- /dev/null +++ b/packages/json-rpc/src/compatibility.ts @@ -0,0 +1,73 @@ +/** + * A single JSON value. This is the missing return type of JSON.parse(). + */ +export type JsonCompatibleValue = + | JsonCompatibleDictionary + | JsonCompatibleArray + | string + | number + | boolean + | null; + +/** + * An array of JsonCompatibleValue + */ +// Use interface extension instead of type alias to make circular declaration possible. +export interface JsonCompatibleArray extends ReadonlyArray {} + +/** + * A string to json value dictionary. + */ +export interface JsonCompatibleDictionary { + readonly [key: string]: JsonCompatibleValue | readonly JsonCompatibleValue[]; +} + +export function isJsonCompatibleValue(value: unknown): value is JsonCompatibleValue { + if ( + typeof value === "string" || + typeof value === "number" || + typeof value === "boolean" || + value === null || + // eslint-disable-next-line @typescript-eslint/no-use-before-define + isJsonCompatibleArray(value) || + // eslint-disable-next-line @typescript-eslint/no-use-before-define + isJsonCompatibleDictionary(value) + ) { + return true; + } else { + return false; + } +} + +export function isJsonCompatibleArray(value: unknown): value is JsonCompatibleArray { + if (!Array.isArray(value)) { + return false; + } + + for (const item of value) { + if (!isJsonCompatibleValue(item)) { + return false; + } + } + + // all items okay + return true; +} + +export function isJsonCompatibleDictionary(data: unknown): data is JsonCompatibleDictionary { + if (typeof data !== "object" || data === null) { + // data must be a non-null object + return false; + } + + // Exclude special kind of objects like Array, Date or Uint8Array + // Object.prototype.toString() returns a specified value: + // http://www.ecma-international.org/ecma-262/7.0/index.html#sec-object.prototype.tostring + if (Object.prototype.toString.call(data) !== "[object Object]") { + return false; + } + + // TODO: replace with Object.values when available (ES2017+) + const values = Object.getOwnPropertyNames(data).map((key) => (data as any)[key]); + return values.every(isJsonCompatibleValue); +} diff --git a/packages/json-rpc/types/compatibility.d.ts b/packages/json-rpc/types/compatibility.d.ts new file mode 100644 index 00000000..9187f0d8 --- /dev/null +++ b/packages/json-rpc/types/compatibility.d.ts @@ -0,0 +1,23 @@ +/** + * A single JSON value. This is the missing return type of JSON.parse(). + */ +export declare type JsonCompatibleValue = + | JsonCompatibleDictionary + | JsonCompatibleArray + | string + | number + | boolean + | null; +/** + * An array of JsonCompatibleValue + */ +export interface JsonCompatibleArray extends ReadonlyArray {} +/** + * A string to json value dictionary. + */ +export interface JsonCompatibleDictionary { + readonly [key: string]: JsonCompatibleValue | readonly JsonCompatibleValue[]; +} +export declare function isJsonCompatibleValue(value: unknown): value is JsonCompatibleValue; +export declare function isJsonCompatibleArray(value: unknown): value is JsonCompatibleArray; +export declare function isJsonCompatibleDictionary(data: unknown): data is JsonCompatibleDictionary; From fd38d7ed80dcdf8ef75a793177573c9c573b4aaf Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:02:55 +0200 Subject: [PATCH 06/13] json-rpc: Use JSON compatibility code instead of @iov/encoding --- packages/json-rpc/src/parse.ts | 3 +-- packages/json-rpc/src/types.ts | 2 +- packages/json-rpc/src/workers/dummyservice.worker.ts | 3 +-- packages/json-rpc/types/types.d.ts | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/json-rpc/src/parse.ts b/packages/json-rpc/src/parse.ts index f1e103ee..d76ccf1d 100644 --- a/packages/json-rpc/src/parse.ts +++ b/packages/json-rpc/src/parse.ts @@ -4,8 +4,7 @@ import { isJsonCompatibleValue, JsonCompatibleDictionary, JsonCompatibleValue, -} from "@iov/encoding"; - +} from "./compatibility"; import { JsonRpcError, JsonRpcErrorResponse, diff --git a/packages/json-rpc/src/types.ts b/packages/json-rpc/src/types.ts index 2cfbf76a..edcfcdcb 100644 --- a/packages/json-rpc/src/types.ts +++ b/packages/json-rpc/src/types.ts @@ -1,4 +1,4 @@ -import { JsonCompatibleArray, JsonCompatibleDictionary, JsonCompatibleValue } from "@iov/encoding"; +import { JsonCompatibleArray, JsonCompatibleDictionary, JsonCompatibleValue } from "./compatibility"; export type JsonRpcId = number | string; diff --git a/packages/json-rpc/src/workers/dummyservice.worker.ts b/packages/json-rpc/src/workers/dummyservice.worker.ts index 426e9803..b0319c2f 100644 --- a/packages/json-rpc/src/workers/dummyservice.worker.ts +++ b/packages/json-rpc/src/workers/dummyservice.worker.ts @@ -2,8 +2,7 @@ // for testing only -import { isJsonCompatibleDictionary } from "@iov/encoding"; - +import { isJsonCompatibleDictionary } from "../compatibility"; import { parseJsonRpcId, parseJsonRpcRequest } from "../parse"; import { jsonRpcCode, diff --git a/packages/json-rpc/types/types.d.ts b/packages/json-rpc/types/types.d.ts index 6a85ad93..6ff60e2a 100644 --- a/packages/json-rpc/types/types.d.ts +++ b/packages/json-rpc/types/types.d.ts @@ -1,4 +1,4 @@ -import { JsonCompatibleArray, JsonCompatibleDictionary, JsonCompatibleValue } from "@iov/encoding"; +import { JsonCompatibleArray, JsonCompatibleDictionary, JsonCompatibleValue } from "./compatibility"; export declare type JsonRpcId = number | string; export interface JsonRpcRequest { readonly jsonrpc: "2.0"; From 5a5747cdefa932f4b6c5c25f07677f52f3b17730 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:05:22 +0200 Subject: [PATCH 07/13] json-rpc: Add format-text script --- packages/json-rpc/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/json-rpc/package.json b/packages/json-rpc/package.json index 1b561fb7..7b6032d3 100644 --- a/packages/json-rpc/package.json +++ b/packages/json-rpc/package.json @@ -29,6 +29,7 @@ "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\"", "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", "format": "prettier --write --loglevel warn \"./src/**/*.ts\"", + "format-text": "prettier --write --prose-wrap always --print-width 80 \"./*.md\"", "test-node": "node jasmine-testrunner.js", "test-edge": "yarn pack-web && karma start --single-run --browsers Edge", "test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox", From 9850fda715fa51283943682d3b69c75df1389d0e Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:05:36 +0200 Subject: [PATCH 08/13] json-rpc: Update README --- packages/json-rpc/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/json-rpc/README.md b/packages/json-rpc/README.md index 63a28283..7f24d0b2 100644 --- a/packages/json-rpc/README.md +++ b/packages/json-rpc/README.md @@ -1,12 +1,12 @@ -# @iov/jsonrpc +# @cosmjs/json-rpc -[![npm version](https://img.shields.io/npm/v/@iov/jsonrpc.svg)](https://www.npmjs.com/package/@iov/jsonrpc) +[![npm version](https://img.shields.io/npm/v/@cosmjs/json-rpc.svg)](https://www.npmjs.com/package/@cosmjs/json-rpc) -This package provides a light framework for implementing a [JSON-RPC 2.0 API](https://www.jsonrpc.org/specification). +This package provides a light framework for implementing a +[JSON-RPC 2.0 API](https://www.jsonrpc.org/specification). ## License -This package is part of the IOV-Core repository, licensed under the Apache -License 2.0 (see -[NOTICE](https://github.com/iov-one/iov-core/blob/master/NOTICE) and -[LICENSE](https://github.com/iov-one/iov-core/blob/master/LICENSE)). +This package is part of the cosmjs repository, licensed under the Apache License +2.0 (see [NOTICE](https://github.com/CosmWasm/cosmjs/blob/master/NOTICE) and +[LICENSE](https://github.com/CosmWasm/cosmjs/blob/master/LICENSE)). From f53d26911f3a2c298a07ef970bbd4f6424fbdde6 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:08:36 +0200 Subject: [PATCH 09/13] root: Update NOTICE for json-rpc --- NOTICE | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NOTICE b/NOTICE index db3598d9..4e23c6ce 100644 --- a/NOTICE +++ b/NOTICE @@ -19,6 +19,8 @@ on 2020-06-05. The code in packages/tendermint-rpc and scripts/tendermint was forked from the folders packages/iov-tendermint-rpc and scripts/tendermint respectively of https://github.com/iov-one/iov-core at tag v2.5.0 on 2020-06-15. +The code in packages/json-rpc was forked from https://github.com/iov-one/iov-core/tree/v2.5.0/packages/iov-jsonrpc, with additional code from https://github.com/iov-one/iov-core/tree/v2.5.0/packages/iov-encoding on 2020-06-24. + Copyright 2018-2020 IOV SAS Copyright 2020 Confio UO Copyright 2020 Simon Warta From 2071b73777de64c3f83d957a51500918b8af75c9 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:12:33 +0200 Subject: [PATCH 10/13] tendermint-rpc: Replace @iov/jsonrpc with @cosmjs/json-rpc --- packages/tendermint-rpc/package.json | 2 +- yarn.lock | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/packages/tendermint-rpc/package.json b/packages/tendermint-rpc/package.json index 71ec1ea0..597aa9f8 100644 --- a/packages/tendermint-rpc/package.json +++ b/packages/tendermint-rpc/package.json @@ -45,8 +45,8 @@ "dependencies": { "@cosmjs/crypto": "^0.20.0", "@cosmjs/encoding": "^0.20.0", + "@cosmjs/json-rpc": "^0.20.0", "@cosmjs/math": "^0.20.0", - "@iov/jsonrpc": "^2.3.2", "@iov/socket": "^2.3.2", "axios": "^0.19.0", "readonly-date": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 02e874ef..e7840788 100644 --- a/yarn.lock +++ b/yarn.lock @@ -92,25 +92,6 @@ unique-filename "^1.1.1" which "^1.3.1" -"@iov/encoding@^2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@iov/encoding/-/encoding-2.3.2.tgz#4b37966af0345a6bc904bb58189dc1ea9d14ad9b" - integrity sha512-viioqo1flTkG4Oxb0PvoBXGozHq9fObAgAL4dRHJe9zmChE77EBX2Y5u0nabd2JwAhEbir56AtsrUe4dOrtd5w== - dependencies: - base64-js "^1.3.0" - bech32 "^1.1.4" - bn.js "^4.11.8" - readonly-date "^1.0.0" - -"@iov/jsonrpc@^2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@iov/jsonrpc/-/jsonrpc-2.3.2.tgz#5cdfa56333741073cc00f17d54efb9f526b9705a" - integrity sha512-fPryTYZ4na1F/K0AF4eRjf1mwg97s8N/AgvELHyqpm7Bq9zvV0/ZBPvzjV1mqmPMfONx91qLIkpDguwmwEb8NA== - dependencies: - "@iov/encoding" "^2.3.2" - "@iov/stream" "^2.3.2" - xstream "^11.10.0" - "@iov/socket@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@iov/socket/-/socket-2.3.2.tgz#adc8ef389bafc5380e1c7415fb21f9a890d79195" From e0db5cbd8aafc5090ddcc1a1b6edbbacc710383e Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:16:40 +0200 Subject: [PATCH 11/13] tendermint-rpc: Use @cosmjs/json-rpc in code --- packages/tendermint-rpc/src/adaptor.ts | 2 +- packages/tendermint-rpc/src/jsonrpc.ts | 2 +- packages/tendermint-rpc/src/rpcclients/httpclient.ts | 2 +- packages/tendermint-rpc/src/rpcclients/rpcclient.ts | 2 +- packages/tendermint-rpc/src/rpcclients/websocketclient.ts | 2 +- packages/tendermint-rpc/src/v0-33/requests.ts | 2 +- packages/tendermint-rpc/src/v0-33/responses.ts | 2 +- packages/tendermint-rpc/types/adaptor.d.ts | 2 +- packages/tendermint-rpc/types/jsonrpc.d.ts | 2 +- packages/tendermint-rpc/types/rpcclients/httpclient.d.ts | 2 +- packages/tendermint-rpc/types/rpcclients/rpcclient.d.ts | 2 +- packages/tendermint-rpc/types/rpcclients/websocketclient.d.ts | 2 +- packages/tendermint-rpc/types/v0-33/requests.d.ts | 2 +- packages/tendermint-rpc/types/v0-33/responses.d.ts | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/tendermint-rpc/src/adaptor.ts b/packages/tendermint-rpc/src/adaptor.ts index 8638ed61..4f188d7c 100644 --- a/packages/tendermint-rpc/src/adaptor.ts +++ b/packages/tendermint-rpc/src/adaptor.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest, JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcRequest, JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import * as requests from "./requests"; import * as responses from "./responses"; diff --git a/packages/tendermint-rpc/src/jsonrpc.ts b/packages/tendermint-rpc/src/jsonrpc.ts index 0b944bd3..6d9ed313 100644 --- a/packages/tendermint-rpc/src/jsonrpc.ts +++ b/packages/tendermint-rpc/src/jsonrpc.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest } from "@iov/jsonrpc"; +import { JsonRpcRequest } from "@cosmjs/json-rpc"; const numbers = "0123456789"; diff --git a/packages/tendermint-rpc/src/rpcclients/httpclient.ts b/packages/tendermint-rpc/src/rpcclients/httpclient.ts index e909fc22..42950660 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpclient.ts @@ -3,7 +3,7 @@ import { JsonRpcRequest, JsonRpcSuccessResponse, parseJsonRpcResponse, -} from "@iov/jsonrpc"; +} from "@cosmjs/json-rpc"; import axios from "axios"; import { hasProtocol, RpcClient } from "./rpcclient"; diff --git a/packages/tendermint-rpc/src/rpcclients/rpcclient.ts b/packages/tendermint-rpc/src/rpcclients/rpcclient.ts index 8783026b..0e358422 100644 --- a/packages/tendermint-rpc/src/rpcclients/rpcclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/rpcclient.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest, JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcRequest, JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { Stream } from "xstream"; /** diff --git a/packages/tendermint-rpc/src/rpcclients/websocketclient.ts b/packages/tendermint-rpc/src/rpcclients/websocketclient.ts index 9d84f817..5b12912d 100644 --- a/packages/tendermint-rpc/src/rpcclients/websocketclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/websocketclient.ts @@ -5,7 +5,7 @@ import { JsonRpcResponse, JsonRpcSuccessResponse, parseJsonRpcResponse, -} from "@iov/jsonrpc"; +} from "@cosmjs/json-rpc"; import { ConnectionStatus, ReconnectingSocket, SocketWrapperMessageEvent } from "@iov/socket"; import { firstEvent } from "@iov/stream"; import { Listener, Producer, Stream, Subscription } from "xstream"; diff --git a/packages/tendermint-rpc/src/v0-33/requests.ts b/packages/tendermint-rpc/src/v0-33/requests.ts index 7526fe0a..3aa8333b 100644 --- a/packages/tendermint-rpc/src/v0-33/requests.ts +++ b/packages/tendermint-rpc/src/v0-33/requests.ts @@ -1,5 +1,5 @@ import { toHex } from "@cosmjs/encoding"; -import { JsonRpcRequest } from "@iov/jsonrpc"; +import { JsonRpcRequest } from "@cosmjs/json-rpc"; import { assertNotEmpty, Base64, Base64String, HexString, Integer, IntegerString, may } from "../encodings"; import { createJsonRpcRequest } from "../jsonrpc"; diff --git a/packages/tendermint-rpc/src/v0-33/responses.ts b/packages/tendermint-rpc/src/v0-33/responses.ts index 90b2bed4..9190c01d 100644 --- a/packages/tendermint-rpc/src/v0-33/responses.ts +++ b/packages/tendermint-rpc/src/v0-33/responses.ts @@ -1,5 +1,5 @@ import { fromHex } from "@cosmjs/encoding"; -import { JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { assertArray, diff --git a/packages/tendermint-rpc/types/adaptor.d.ts b/packages/tendermint-rpc/types/adaptor.d.ts index 94fb1971..9dde507b 100644 --- a/packages/tendermint-rpc/types/adaptor.d.ts +++ b/packages/tendermint-rpc/types/adaptor.d.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest, JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcRequest, JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import * as requests from "./requests"; import * as responses from "./responses"; import { SubscriptionEvent } from "./rpcclients"; diff --git a/packages/tendermint-rpc/types/jsonrpc.d.ts b/packages/tendermint-rpc/types/jsonrpc.d.ts index c420a2f2..0d3b7802 100644 --- a/packages/tendermint-rpc/types/jsonrpc.d.ts +++ b/packages/tendermint-rpc/types/jsonrpc.d.ts @@ -1,3 +1,3 @@ -import { JsonRpcRequest } from "@iov/jsonrpc"; +import { JsonRpcRequest } from "@cosmjs/json-rpc"; /** Creates a JSON-RPC request with random ID */ export declare function createJsonRpcRequest(method: string, params?: {}): JsonRpcRequest; diff --git a/packages/tendermint-rpc/types/rpcclients/httpclient.d.ts b/packages/tendermint-rpc/types/rpcclients/httpclient.d.ts index 09ee652b..8b50c1d3 100644 --- a/packages/tendermint-rpc/types/rpcclients/httpclient.d.ts +++ b/packages/tendermint-rpc/types/rpcclients/httpclient.d.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest, JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcRequest, JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { RpcClient } from "./rpcclient"; export declare class HttpClient implements RpcClient { protected readonly url: string; diff --git a/packages/tendermint-rpc/types/rpcclients/rpcclient.d.ts b/packages/tendermint-rpc/types/rpcclients/rpcclient.d.ts index 8ef11353..9089d78f 100644 --- a/packages/tendermint-rpc/types/rpcclients/rpcclient.d.ts +++ b/packages/tendermint-rpc/types/rpcclients/rpcclient.d.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest, JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcRequest, JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { Stream } from "xstream"; /** * An event emitted from Tendermint after subscribing via RPC. diff --git a/packages/tendermint-rpc/types/rpcclients/websocketclient.d.ts b/packages/tendermint-rpc/types/rpcclients/websocketclient.d.ts index 4caae6a0..36db855a 100644 --- a/packages/tendermint-rpc/types/rpcclients/websocketclient.d.ts +++ b/packages/tendermint-rpc/types/rpcclients/websocketclient.d.ts @@ -1,4 +1,4 @@ -import { JsonRpcId, JsonRpcRequest, JsonRpcResponse, JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcId, JsonRpcRequest, JsonRpcResponse, JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { Stream } from "xstream"; import { RpcStreamingClient, SubscriptionEvent } from "./rpcclient"; export declare class WebsocketClient implements RpcStreamingClient { diff --git a/packages/tendermint-rpc/types/v0-33/requests.d.ts b/packages/tendermint-rpc/types/v0-33/requests.d.ts index af972c4a..bdfaa960 100644 --- a/packages/tendermint-rpc/types/v0-33/requests.d.ts +++ b/packages/tendermint-rpc/types/v0-33/requests.d.ts @@ -1,4 +1,4 @@ -import { JsonRpcRequest } from "@iov/jsonrpc"; +import { JsonRpcRequest } from "@cosmjs/json-rpc"; import * as requests from "../requests"; export declare class Params { static encodeAbciInfo(req: requests.AbciInfoRequest): JsonRpcRequest; diff --git a/packages/tendermint-rpc/types/v0-33/responses.d.ts b/packages/tendermint-rpc/types/v0-33/responses.d.ts index 05fad338..454efc04 100644 --- a/packages/tendermint-rpc/types/v0-33/responses.d.ts +++ b/packages/tendermint-rpc/types/v0-33/responses.d.ts @@ -1,4 +1,4 @@ -import { JsonRpcSuccessResponse } from "@iov/jsonrpc"; +import { JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import * as responses from "../responses"; import { SubscriptionEvent } from "../rpcclients"; export declare class Responses { From 1699cb0e87fdecb787eb48885d8e185861549fbc Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:32:14 +0200 Subject: [PATCH 12/13] tendermint-rpc: Update comment --- packages/tendermint-rpc/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tendermint-rpc/src/types.ts b/packages/tendermint-rpc/src/types.ts index 29c33641..0c259f83 100644 --- a/packages/tendermint-rpc/src/types.ts +++ b/packages/tendermint-rpc/src/types.ts @@ -1,4 +1,4 @@ -// Types in this file are exported outside of the @iov/tendermint-rpc package, +// Types in this file are exported outside of the @cosmjs/tendermint-rpc package, // e.g. as part of a request or response import { As } from "type-tagger"; From aa973a4c70ebca472b9843fc2335bd1832e6c6df Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 24 Jun 2020 16:44:09 +0200 Subject: [PATCH 13/13] json-rpc: Remove nonces --- packages/json-rpc/nonces/1552895838 | 0 packages/json-rpc/nonces/1553085893 | 0 packages/json-rpc/nonces/1554721221 | 0 packages/json-rpc/nonces/1554724217 | 0 packages/json-rpc/nonces/1554737147 | 0 packages/json-rpc/nonces/1555314694 | 0 packages/json-rpc/nonces/1556008552 | 0 packages/json-rpc/nonces/1556028926 | 0 packages/json-rpc/nonces/1556095341 | 0 packages/json-rpc/nonces/1556616100 | 0 packages/json-rpc/nonces/1557811966 | 0 packages/json-rpc/nonces/1558346811 | 0 packages/json-rpc/nonces/1558456815 | 0 packages/json-rpc/nonces/1558460837 | 0 packages/json-rpc/nonces/1559802671 | 0 packages/json-rpc/nonces/1561970534 | 0 packages/json-rpc/nonces/1562080432 | 0 packages/json-rpc/nonces/1563468776 | 0 packages/json-rpc/nonces/1563887488 | 0 packages/json-rpc/nonces/1563960408 | 0 packages/json-rpc/nonces/1563981076 | 0 packages/json-rpc/nonces/1564503008 | 0 packages/json-rpc/nonces/1564651088 | 0 packages/json-rpc/nonces/1565101189 | 0 packages/json-rpc/nonces/1565595547 | 0 packages/json-rpc/nonces/1565876849 | 0 packages/json-rpc/nonces/1566487600 | 0 packages/json-rpc/nonces/1567435567 | 0 packages/json-rpc/nonces/1567608963 | 0 packages/json-rpc/nonces/1567694160 | 0 packages/json-rpc/nonces/1568039925 | 0 packages/json-rpc/nonces/1568116477 | 0 packages/json-rpc/nonces/1568786866 | 0 packages/json-rpc/nonces/1568910632 | 0 packages/json-rpc/nonces/1569319493 | 0 packages/json-rpc/nonces/1569487848 | 0 packages/json-rpc/nonces/1569929617 | 0 packages/json-rpc/nonces/1570527883 | 0 packages/json-rpc/nonces/1573026590 | 0 packages/json-rpc/nonces/1574869843 | 0 packages/json-rpc/nonces/1576569788 | 0 packages/json-rpc/nonces/1576595306 | 0 packages/json-rpc/nonces/1576678551 | 0 packages/json-rpc/nonces/1576746493 | 0 packages/json-rpc/nonces/1576760285 | 0 packages/json-rpc/nonces/1576767119 | 0 packages/json-rpc/nonces/1579019908 | 0 packages/json-rpc/nonces/1581606289 | 0 packages/json-rpc/nonces/1581681020 | 0 packages/json-rpc/nonces/1584038020 | 0 packages/json-rpc/nonces/1588011428 | 0 packages/json-rpc/nonces/1591293896 | 0 52 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/json-rpc/nonces/1552895838 delete mode 100644 packages/json-rpc/nonces/1553085893 delete mode 100644 packages/json-rpc/nonces/1554721221 delete mode 100644 packages/json-rpc/nonces/1554724217 delete mode 100644 packages/json-rpc/nonces/1554737147 delete mode 100644 packages/json-rpc/nonces/1555314694 delete mode 100644 packages/json-rpc/nonces/1556008552 delete mode 100644 packages/json-rpc/nonces/1556028926 delete mode 100644 packages/json-rpc/nonces/1556095341 delete mode 100644 packages/json-rpc/nonces/1556616100 delete mode 100644 packages/json-rpc/nonces/1557811966 delete mode 100644 packages/json-rpc/nonces/1558346811 delete mode 100644 packages/json-rpc/nonces/1558456815 delete mode 100644 packages/json-rpc/nonces/1558460837 delete mode 100644 packages/json-rpc/nonces/1559802671 delete mode 100644 packages/json-rpc/nonces/1561970534 delete mode 100644 packages/json-rpc/nonces/1562080432 delete mode 100644 packages/json-rpc/nonces/1563468776 delete mode 100644 packages/json-rpc/nonces/1563887488 delete mode 100644 packages/json-rpc/nonces/1563960408 delete mode 100644 packages/json-rpc/nonces/1563981076 delete mode 100644 packages/json-rpc/nonces/1564503008 delete mode 100644 packages/json-rpc/nonces/1564651088 delete mode 100644 packages/json-rpc/nonces/1565101189 delete mode 100644 packages/json-rpc/nonces/1565595547 delete mode 100644 packages/json-rpc/nonces/1565876849 delete mode 100644 packages/json-rpc/nonces/1566487600 delete mode 100644 packages/json-rpc/nonces/1567435567 delete mode 100644 packages/json-rpc/nonces/1567608963 delete mode 100644 packages/json-rpc/nonces/1567694160 delete mode 100644 packages/json-rpc/nonces/1568039925 delete mode 100644 packages/json-rpc/nonces/1568116477 delete mode 100644 packages/json-rpc/nonces/1568786866 delete mode 100644 packages/json-rpc/nonces/1568910632 delete mode 100644 packages/json-rpc/nonces/1569319493 delete mode 100644 packages/json-rpc/nonces/1569487848 delete mode 100644 packages/json-rpc/nonces/1569929617 delete mode 100644 packages/json-rpc/nonces/1570527883 delete mode 100644 packages/json-rpc/nonces/1573026590 delete mode 100644 packages/json-rpc/nonces/1574869843 delete mode 100644 packages/json-rpc/nonces/1576569788 delete mode 100644 packages/json-rpc/nonces/1576595306 delete mode 100644 packages/json-rpc/nonces/1576678551 delete mode 100644 packages/json-rpc/nonces/1576746493 delete mode 100644 packages/json-rpc/nonces/1576760285 delete mode 100644 packages/json-rpc/nonces/1576767119 delete mode 100644 packages/json-rpc/nonces/1579019908 delete mode 100644 packages/json-rpc/nonces/1581606289 delete mode 100644 packages/json-rpc/nonces/1581681020 delete mode 100644 packages/json-rpc/nonces/1584038020 delete mode 100644 packages/json-rpc/nonces/1588011428 delete mode 100644 packages/json-rpc/nonces/1591293896 diff --git a/packages/json-rpc/nonces/1552895838 b/packages/json-rpc/nonces/1552895838 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1553085893 b/packages/json-rpc/nonces/1553085893 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1554721221 b/packages/json-rpc/nonces/1554721221 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1554724217 b/packages/json-rpc/nonces/1554724217 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1554737147 b/packages/json-rpc/nonces/1554737147 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1555314694 b/packages/json-rpc/nonces/1555314694 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1556008552 b/packages/json-rpc/nonces/1556008552 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1556028926 b/packages/json-rpc/nonces/1556028926 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1556095341 b/packages/json-rpc/nonces/1556095341 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1556616100 b/packages/json-rpc/nonces/1556616100 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1557811966 b/packages/json-rpc/nonces/1557811966 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1558346811 b/packages/json-rpc/nonces/1558346811 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1558456815 b/packages/json-rpc/nonces/1558456815 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1558460837 b/packages/json-rpc/nonces/1558460837 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1559802671 b/packages/json-rpc/nonces/1559802671 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1561970534 b/packages/json-rpc/nonces/1561970534 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1562080432 b/packages/json-rpc/nonces/1562080432 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1563468776 b/packages/json-rpc/nonces/1563468776 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1563887488 b/packages/json-rpc/nonces/1563887488 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1563960408 b/packages/json-rpc/nonces/1563960408 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1563981076 b/packages/json-rpc/nonces/1563981076 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1564503008 b/packages/json-rpc/nonces/1564503008 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1564651088 b/packages/json-rpc/nonces/1564651088 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1565101189 b/packages/json-rpc/nonces/1565101189 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1565595547 b/packages/json-rpc/nonces/1565595547 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1565876849 b/packages/json-rpc/nonces/1565876849 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1566487600 b/packages/json-rpc/nonces/1566487600 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1567435567 b/packages/json-rpc/nonces/1567435567 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1567608963 b/packages/json-rpc/nonces/1567608963 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1567694160 b/packages/json-rpc/nonces/1567694160 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1568039925 b/packages/json-rpc/nonces/1568039925 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1568116477 b/packages/json-rpc/nonces/1568116477 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1568786866 b/packages/json-rpc/nonces/1568786866 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1568910632 b/packages/json-rpc/nonces/1568910632 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1569319493 b/packages/json-rpc/nonces/1569319493 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1569487848 b/packages/json-rpc/nonces/1569487848 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1569929617 b/packages/json-rpc/nonces/1569929617 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1570527883 b/packages/json-rpc/nonces/1570527883 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1573026590 b/packages/json-rpc/nonces/1573026590 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1574869843 b/packages/json-rpc/nonces/1574869843 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1576569788 b/packages/json-rpc/nonces/1576569788 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1576595306 b/packages/json-rpc/nonces/1576595306 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1576678551 b/packages/json-rpc/nonces/1576678551 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1576746493 b/packages/json-rpc/nonces/1576746493 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1576760285 b/packages/json-rpc/nonces/1576760285 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1576767119 b/packages/json-rpc/nonces/1576767119 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1579019908 b/packages/json-rpc/nonces/1579019908 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1581606289 b/packages/json-rpc/nonces/1581606289 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1581681020 b/packages/json-rpc/nonces/1581681020 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1584038020 b/packages/json-rpc/nonces/1584038020 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1588011428 b/packages/json-rpc/nonces/1588011428 deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/json-rpc/nonces/1591293896 b/packages/json-rpc/nonces/1591293896 deleted file mode 100644 index e69de29b..00000000