user пре 6 година
родитељ
комит
6b89fa6825
10 измењених фајлова са 394 додато и 52 уклоњено
  1. 20 6
      .vscode/launch.json
  2. 33 0
      __tests__/index.test.ts
  3. 187 38
      package-lock.json
  4. 5 1
      package.json
  5. 62 2
      src/index.ts
  6. 54 0
      src/util.ts
  7. 26 0
      src/webclient-node.ts
  8. 2 1
      src/webclient-options.ts
  9. 3 3
      src/webclient.ts
  10. 2 1
      tsconfig.json

+ 20 - 6
.vscode/launch.json

@@ -5,14 +5,28 @@
     "version": "0.2.0",
     "configurations": [
         {
-            "name": "Current TS File",
             "type": "node",
             "request": "launch",
-            "args": ["${relativeFile}"],
-            "runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
-            "sourceMaps": true,
-            "cwd": "${workspaceRoot}",
-            "protocol": "inspector",
+            "name": "Debug Jest Tests",
+            "cwd": "${workspaceFolder}",
+            "args": [
+              "--inspect-brk",
+              "${workspaceRoot}/node_modules/.bin/jest",
+              "--runInBand",
+              "--config",
+              "${workspaceRoot}/jestconfig.json"
+            ],
+            "windows": {
+              "args": [
+                "--inspect-brk",
+                "${workspaceRoot}/node_modules/jest/bin/jest.js",
+                "--runInBand",
+                "--config",
+                "${workspaceRoot}/jestconfig.json"          
+              ],
+            },
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen"
         },
         {
             "type": "node",

+ 33 - 0
__tests__/index.test.ts

@@ -1,5 +1,7 @@
+import nock from 'nock';
 import { BankClient } from '../src/index';
 import { IWebClient } from '../src/webclient';
+import WebClientNode from '../src/webclient-node';
 import { Storage } from './../src/storage';
 import { IWebClientOptions } from './../src/webclient-options';
 
@@ -34,4 +36,35 @@ describe('BankClient', () => {
       const nonce = await bankClient.getNonce();
       expect(nonce).toEqual(42);
   });
+
+  describe('get nonce', () => {
+    test('should work with real http client', async () => {
+      const webClient = new WebClientNode();
+      const bankClient = new BankClient('http://127.0.0.1:8000', storage, webClient);
+      await bankClient.bootstrap();
+      nock('http://127.0.0.1:8000')
+        .get('/bank/nonce')
+        .reply(200, "42");
+      const nonce = await bankClient.getNonce();
+      expect(nonce).toEqual(42);
+    });
+  });
+
+  describe('get balance', () => {
+    test('should work with real http client', async () => {
+      const webClient = new WebClientNode();
+      const bankClient = new BankClient('http://127.0.0.1:8000', storage, webClient);
+      await bankClient.bootstrap();
+      nock('http://127.0.0.1:8000')
+        .post('/bank/getbalance')
+        .reply(200, {
+          what: 'true'
+        });
+      nock('http://127.0.0.1:8000')
+      .get('/bank/nonce')
+      .reply(200, "42");
+      const balance = await bankClient.getBalance();
+      expect(balance).toEqual({what: 'true'});
+    });
+  });
 });

+ 187 - 38
package-lock.json

@@ -432,6 +432,27 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "@types/bluebird": {
+      "version": "3.5.27",
+      "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.27.tgz",
+      "integrity": "sha512-6BmYWSBea18+tSjjSC3QIyV93ZKAeNWGM7R6aYt1ryTZXrlHF+QLV0G2yV0viEGVyRkyQsWfMoJ0k/YghBX5sQ==",
+      "dev": true
+    },
+    "@types/caseless": {
+      "version": "0.12.2",
+      "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
+      "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
+      "dev": true
+    },
+    "@types/form-data": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
+      "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/istanbul-lib-coverage": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
@@ -472,18 +493,55 @@
       "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==",
       "dev": true
     },
+    "@types/nock": {
+      "version": "10.0.3",
+      "resolved": "https://registry.npmjs.org/@types/nock/-/nock-10.0.3.tgz",
+      "integrity": "sha512-OthuN+2FuzfZO3yONJ/QVjKmLEuRagS9TV9lEId+WHL9KhftYG+/2z+pxlr0UgVVXSpVD8woie/3fzQn8ft/Ow==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/node": {
       "version": "12.6.2",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.2.tgz",
       "integrity": "sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ==",
       "dev": true
     },
+    "@types/request": {
+      "version": "2.48.1",
+      "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz",
+      "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==",
+      "dev": true,
+      "requires": {
+        "@types/caseless": "*",
+        "@types/form-data": "*",
+        "@types/node": "*",
+        "@types/tough-cookie": "*"
+      }
+    },
+    "@types/request-promise": {
+      "version": "4.1.44",
+      "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.44.tgz",
+      "integrity": "sha512-RId7eFsUKxfal1LirDDIcOp9u3MM3NXFDBcC3sqIMcmu7f4U6DsCEMD8RbLZtnPrQlN5Jc79di/WPsIEDO4keg==",
+      "dev": true,
+      "requires": {
+        "@types/bluebird": "*",
+        "@types/request": "*"
+      }
+    },
     "@types/stack-utils": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
       "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
       "dev": true
     },
+    "@types/tough-cookie": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz",
+      "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==",
+      "dev": true
+    },
     "@types/yargs": {
       "version": "12.0.12",
       "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.12.tgz",
@@ -644,6 +702,12 @@
       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
       "dev": true
     },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
     "assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -846,6 +910,11 @@
       "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
       "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
     },
+    "bluebird": {
+      "version": "3.5.5",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
+      "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
+    },
     "bn.js": {
       "version": "4.11.8",
       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
@@ -1018,6 +1087,20 @@
       "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
       "dev": true
     },
+    "chai": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+      "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+      "dev": true,
+      "requires": {
+        "assertion-error": "^1.1.0",
+        "check-error": "^1.0.2",
+        "deep-eql": "^3.0.1",
+        "get-func-name": "^2.0.0",
+        "pathval": "^1.1.0",
+        "type-detect": "^4.0.5"
+      }
+    },
     "chalk": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -1029,6 +1112,12 @@
         "supports-color": "^5.3.0"
       }
     },
+    "check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true
+    },
     "ci-info": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
@@ -1295,6 +1384,21 @@
       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
       "dev": true
     },
+    "deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "requires": {
+        "type-detect": "^4.0.0"
+      }
+    },
+    "deep-equal": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
+      "dev": true
+    },
     "deep-is": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -1811,8 +1915,7 @@
         "ansi-regex": {
           "version": "2.1.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -1833,14 +1936,12 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -1855,20 +1956,17 @@
         "code-point-at": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -1985,8 +2083,7 @@
         "inherits": {
           "version": "2.0.3",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "ini": {
           "version": "1.3.5",
@@ -1998,7 +2095,6 @@
           "version": "1.0.0",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -2013,7 +2109,6 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -2021,14 +2116,12 @@
         "minimist": {
           "version": "0.0.8",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -2047,7 +2140,6 @@
           "version": "0.5.1",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -2128,8 +2220,7 @@
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -2141,7 +2232,6 @@
           "version": "1.4.0",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -2227,8 +2317,7 @@
         "safe-buffer": {
           "version": "5.1.2",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -2264,7 +2353,6 @@
           "version": "1.0.2",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -2284,7 +2372,6 @@
           "version": "3.0.1",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -2328,14 +2415,12 @@
         "wrappy": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "yallist": {
           "version": "3.0.3",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         }
       }
     },
@@ -2351,6 +2436,12 @@
       "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
       "dev": true
     },
+    "get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true
+    },
     "get-stream": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -3848,6 +3939,40 @@
       "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
       "dev": true
     },
+    "nock": {
+      "version": "10.0.6",
+      "resolved": "https://registry.npmjs.org/nock/-/nock-10.0.6.tgz",
+      "integrity": "sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w==",
+      "dev": true,
+      "requires": {
+        "chai": "^4.1.2",
+        "debug": "^4.1.0",
+        "deep-equal": "^1.0.0",
+        "json-stringify-safe": "^5.0.1",
+        "lodash": "^4.17.5",
+        "mkdirp": "^0.5.0",
+        "propagate": "^1.0.0",
+        "qs": "^6.5.1",
+        "semver": "^5.5.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
     "node-forge": {
       "version": "0.7.6",
       "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz",
@@ -4167,6 +4292,12 @@
         "pify": "^3.0.0"
       }
     },
+    "pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true
+    },
     "pem-jwk": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/pem-jwk/-/pem-jwk-2.0.0.tgz",
@@ -4265,6 +4396,12 @@
         "sisteransi": "^1.0.0"
       }
     },
+    "propagate": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz",
+      "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=",
+      "dev": true
+    },
     "protocol-buffers-schema": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz",
@@ -4284,8 +4421,7 @@
     "psl": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
-      "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
-      "dev": true
+      "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA=="
     },
     "pump": {
       "version": "3.0.0",
@@ -4300,8 +4436,7 @@
     "punycode": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
     },
     "qs": {
       "version": "6.5.2",
@@ -4442,11 +4577,21 @@
         }
       }
     },
+    "request-promise": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz",
+      "integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==",
+      "requires": {
+        "bluebird": "^3.5.0",
+        "request-promise-core": "1.1.2",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      }
+    },
     "request-promise-core": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
       "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
-      "dev": true,
       "requires": {
         "lodash": "^4.17.11"
       }
@@ -4958,8 +5103,7 @@
     "stealthy-require": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
-      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
-      "dev": true
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
     },
     "string-length": {
       "version": "2.0.0",
@@ -5144,7 +5288,6 @@
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
       "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
       "requires": {
         "psl": "^1.1.28",
         "punycode": "^2.1.1"
@@ -5285,6 +5428,12 @@
         "prelude-ls": "~1.1.2"
       }
     },
+    "type-detect": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+      "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+      "dev": true
+    },
     "typescript": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",

+ 5 - 1
package.json

@@ -15,8 +15,11 @@
   "license": "ISC",
   "devDependencies": {
     "@types/jest": "^24.0.15",
+    "@types/nock": "^10.0.3",
     "@types/node": "^12.6.2",
+    "@types/request-promise": "^4.1.44",
     "jest": "^24.8.0",
+    "nock": "^10.0.6",
     "prettier": "^1.18.2",
     "ts-jest": "^24.0.2",
     "ts-node": "^8.3.0",
@@ -25,6 +28,7 @@
     "typescript": "^3.5.3"
   },
   "dependencies": {
-    "libp2p-crypto": "^0.16.1"
+    "libp2p-crypto": "^0.16.1",
+    "request-promise": "^4.2.4"
   }
 }

+ 62 - 2
src/index.ts

@@ -1,10 +1,15 @@
 import crypto = require('libp2p-crypto');
+import util = require('util');
+import RsaPrivateKey = crypto.keys;
 import { Storage } from './storage';
 import { IWebClient } from './webclient';
+const TextEncoder = util.TextEncoder;
+
+import { encodeHex } from './util';
 
 export class BankClient {
 
-    private privateKey: any;
+    private privateKey: RsaPrivateKey | undefined;
     private bootstrapPromise: any;
     private bootstrapResult: any;
 
@@ -15,7 +20,7 @@ export class BankClient {
     public getPub(): Promise<string> {
       return new Promise(async (resolve, reject) => {
         await this.bootstrap();
-        this.privateKey.id((idErr, pubHash) => {
+        this.getPriv().id((idErr, pubHash) => {
           if (idErr) {
             return reject(idErr);
           }
@@ -73,4 +78,59 @@ export class BankClient {
       });
       return Number(nonce);
     }
+
+    public async getBalance() {
+      const nonce = await this.getNonce();
+      const retrieveRequest = await this.makePlaintextPayload(JSON.stringify({
+        _date: new Date().toISOString(),
+        _nonce: nonce
+      }));
+  
+      const topicURL = this.urlBase + '/bank/getbalance';
+      const postResponse = this.webClient.requestJSON({
+        body: retrieveRequest,
+        method: 'POST',
+        url: topicURL
+      });
+      return postResponse;
+    }
+
+
+
+    private getPriv(): RsaPrivateKey {
+      if (!this.privateKey) {
+        throw new Error('missing private key');
+      }
+      return this.privateKey;
+    }
+
+    private makePlaintextPayload(message: string) {
+      const messageBytes = new TextEncoder().encode(message);
+  
+      return new Promise(async (resolve, reject) => {
+        await this.bootstrap();
+        this.privateKey.sign(messageBytes, async (signErr, signatureBytes) => {
+          if (signErr) {
+            reject(signErr);
+            return;
+          }
+          const publicDERBytes = this.privateKey.public.bytes;
+          this.privateKey.id((idErr, pubHash) => {
+            if (idErr) {
+              reject(idErr);
+              return;
+            }
+            const result = {
+              date: new Date().toISOString(),
+              msg: encodeHex(messageBytes),
+              pub: encodeHex(publicDERBytes),
+              pubHash,
+              sig: encodeHex(signatureBytes),
+            };
+            // console.log('result', result, signatureBytes);
+            resolve(result);
+          });
+        });
+      });
+    }
 }

+ 54 - 0
src/util.ts

@@ -0,0 +1,54 @@
+function toArray(msg, enc) {
+    if (Array.isArray(msg)) {
+      return msg.slice();
+    }
+    if (!msg) {
+      return [];
+    }
+    const res: number[] = [];
+    if (typeof msg !== 'string') {
+      for (let i = 0; i < msg.length; i++) {
+        res[i] = msg[i] | 0;
+      }
+      return res;
+    }
+    if (enc === 'hex') {
+      msg = msg.replace(/[^a-z0-9]+/ig, '');
+      if (msg.length % 2 !== 0) {
+        msg = '0' + msg;
+      }
+      for (let i = 0; i < msg.length; i += 2) {
+        res.push(parseInt(msg[i] + msg[i + 1], 16));
+      }
+    } else {
+      for (let i = 0; i < msg.length; i++) {
+        const c = msg.charCodeAt(i);
+        const hi = c >> 8;
+        const lo = c & 0xff;
+        if (hi) {
+          res.push(hi, lo);
+        }
+        else {
+          res.push(lo);
+        }
+      }
+    }
+    return res;
+  }
+  
+  function zero2(word) {
+    if (word.length === 1) {
+      return '0' + word;
+    }
+    else {
+      return word;
+    }
+  }
+    
+  export function encodeHex(msg) {
+    let res = '';
+    for (let i = 0; i < msg.length; i++) {
+      res += zero2(msg[i].toString(16));
+    }
+    return res;
+  }

+ 26 - 0
src/webclient-node.ts

@@ -0,0 +1,26 @@
+import request = require('request-promise');
+import { IWebClient } from "./webclient";
+import { IWebClientOptions } from "./webclient-options";
+
+export default class WebClientNode implements IWebClient {
+
+    public async request(options: IWebClientOptions): Promise<string> {
+        const rpOptions = {
+            method: options.method,
+            uri: options.url
+        };
+        const result = request(rpOptions);
+        return result;
+    }    
+    
+    public async requestJSON(options: IWebClientOptions): Promise<object> {
+        if (!options.headers) {
+            options.headers = {};
+        }
+        if (options.body) {
+            options.headers['content-type'] = 'application/json';
+        }
+        options.headers.accept = 'application/json';
+        return JSON.parse(await this.request(options));
+    }
+}

+ 2 - 1
src/webclient-options.ts

@@ -3,5 +3,6 @@ import { request } from "https";
 export interface IWebClientOptions {
     method: string;
     url: string;
-    headers?: object;
+    headers?: any;
+    body?: any;
 }

+ 3 - 3
src/webclient.ts

@@ -1,6 +1,6 @@
-import { request } from "https";
+import { IWebClientOptions } from "./webclient-options";
 
 export interface IWebClient {
-    request(options: object): Promise<string>;
-    requestJSON(options: object): Promise<object>;
+    request(options: IWebClientOptions): Promise<string>;
+    requestJSON(options: IWebClientOptions): Promise<object>;
 }

+ 2 - 1
tsconfig.json

@@ -6,7 +6,8 @@
       "outDir": "./lib",
       "strict": true,
       "noImplicitAny": false,
-      "sourceMap": true
+      "sourceMap": true,
+      "esModuleInterop": true
     },
     "include": ["src"],
     "exclude": ["node_modules", "**/__tests__/*"]