user 6 yıl önce
ebeveyn
işleme
9e427ba259

+ 14 - 2
lib/index.d.ts

@@ -1,5 +1,17 @@
+import { Storage } from './storage';
+import { IWebClient } from './webclient';
 export declare class BankClient {
     private urlBase;
-    constructor(urlBase: string);
-    upload(): Promise<void>;
+    private storage;
+    private webClient;
+    private privateKey;
+    private bootstrapPromise;
+    private bootstrapResult;
+    constructor(urlBase: string, storage: Storage, webClient: IWebClient);
+    getPub(): Promise<string>;
+    bootstrap(): any;
+    getNonce(): Promise<number>;
+    getBalance(): Promise<object>;
+    private getPriv;
+    private makePlaintextPayload;
 }

+ 120 - 38
lib/index.js

@@ -7,47 +7,129 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
         step((generator = generator.apply(thisArg, _arguments || [])).next());
     });
 };
-var __generator = (this && this.__generator) || function (thisArg, body) {
-    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
-    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
-    function verb(n) { return function (v) { return step([n, v]); }; }
-    function step(op) {
-        if (f) throw new TypeError("Generator is already executing.");
-        while (_) try {
-            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
-            if (y = 0, t) op = [op[0] & 2, t.value];
-            switch (op[0]) {
-                case 0: case 1: t = op; break;
-                case 4: _.label++; return { value: op[1], done: false };
-                case 5: _.label++; y = op[1]; op = [0]; continue;
-                case 7: op = _.ops.pop(); _.trys.pop(); continue;
-                default:
-                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
-                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
-                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
-                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
-                    if (t[2]) _.ops.pop();
-                    _.trys.pop(); continue;
-            }
-            op = body.call(thisArg, _);
-        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
-        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
-    }
-};
 Object.defineProperty(exports, "__esModule", { value: true });
-var BankClient = /** @class */ (function () {
-    function BankClient(urlBase) {
+const crypto = require("libp2p-crypto");
+const util = require("util");
+const TextEncoder = util.TextEncoder;
+const util_1 = require("./util");
+class BankClient {
+    constructor(urlBase, storage, webClient) {
         this.urlBase = urlBase;
+        this.storage = storage;
+        this.webClient = webClient;
+    }
+    getPub() {
+        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
+            yield this.bootstrap();
+            this.getPriv().id((idErr, pubHash) => {
+                if (idErr) {
+                    return reject(idErr);
+                }
+                resolve(pubHash);
+            });
+        }));
+    }
+    bootstrap() {
+        if (this.bootstrapResult) {
+            return Promise.resolve(this.bootstrapResult);
+        }
+        if (this.bootstrapPromise) {
+            return this.bootstrapPromise;
+        }
+        return this.bootstrapPromise = new Promise((resolve, reject) => {
+            this.storage.get('notaprivatekey').then(privateKeyFromStorage => {
+                if (privateKeyFromStorage == null) {
+                    console.log('no private key in storage. generating new');
+                    crypto.keys.generateKeyPair('RSA', 2048, (generateErr, privateKey) => {
+                        if (generateErr) {
+                            return reject(generateErr);
+                        }
+                        privateKey.export('password', (exportErr, exportResult) => {
+                            if (exportErr) {
+                                return reject(exportErr);
+                            }
+                            this.storage.set('notaprivatekey', exportResult).then(err => {
+                                // whatever
+                            }).catch(reject);
+                            this.privateKey = privateKey;
+                            resolve(true);
+                        });
+                    });
+                }
+                else {
+                    // console.log('importing privatekey');
+                    crypto.keys.import(privateKeyFromStorage, 'password', (err, importedPrivateKey) => {
+                        if (err) {
+                            return reject(err);
+                        }
+                        this.privateKey = importedPrivateKey;
+                        // console.log(this.getPublicKeyString());
+                        // console.log(privateKeyFromStorage);
+                        resolve(true);
+                    });
+                }
+            }).catch(reject);
+        });
     }
-    BankClient.prototype.upload = function () {
-        return __awaiter(this, void 0, void 0, function () {
-            return __generator(this, function (_a) {
-                // tslint:disable-next-line: no-console
-                console.log('hey');
-                return [2 /*return*/];
+    getNonce() {
+        return __awaiter(this, void 0, void 0, function* () {
+            const nonce = yield this.webClient.request({
+                method: 'GET',
+                url: this.urlBase + '/bank/nonce'
             });
+            return Number(nonce);
         });
-    };
-    return BankClient;
-}());
+    }
+    getBalance() {
+        return __awaiter(this, void 0, void 0, function* () {
+            const nonce = yield this.getNonce();
+            const retrieveRequest = yield 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;
+        });
+    }
+    getPriv() {
+        if (!this.privateKey) {
+            throw new Error('missing private key');
+        }
+        return this.privateKey;
+    }
+    makePlaintextPayload(message) {
+        const messageBytes = new TextEncoder().encode(message);
+        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
+            yield this.bootstrap();
+            this.privateKey.sign(messageBytes, (signErr, signatureBytes) => __awaiter(this, void 0, void 0, function* () {
+                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: util_1.encodeHex(messageBytes),
+                        pub: util_1.encodeHex(publicDERBytes),
+                        pubHash,
+                        sig: util_1.encodeHex(signatureBytes),
+                    };
+                    // console.log('result', result, signatureBytes);
+                    resolve(result);
+                });
+            }));
+        }));
+    }
+}
 exports.BankClient = BankClient;
+//# sourceMappingURL=index.js.map

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
lib/index.js.map


+ 9 - 0
lib/storage.d.ts

@@ -0,0 +1,9 @@
+export declare class Storage {
+    private prefix;
+    constructor(id: string);
+    getValues(): Promise<unknown[]>;
+    get(key: string): Promise<any>;
+    put(key: string, value: any): Promise<void>;
+    set(key: string, value: any): Promise<void>;
+    private getMap;
+}

+ 68 - 0
lib/storage.js

@@ -0,0 +1,68 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const fs = require("fs");
+class Storage {
+    constructor(id) {
+        try {
+            fs.mkdirSync("data");
+        }
+        catch (e) {
+            // ignore
+        }
+        const safeId = id.replace(/[^A-Za-z0-9]/g, "");
+        if (safeId === '') {
+            throw new Error("must have non-empty id");
+        }
+        this.prefix = safeId;
+    }
+    getValues() {
+        return __awaiter(this, void 0, void 0, function* () {
+            return Object.values(this.getMap());
+        });
+    }
+    get(key) {
+        return __awaiter(this, void 0, void 0, function* () {
+            return this.getMap()[key];
+        });
+    }
+    put(key, value) {
+        return __awaiter(this, void 0, void 0, function* () {
+            const filename = "data/storage_" + this.prefix;
+            let map;
+            try {
+                const contents = fs.readFileSync(filename, { encoding: 'utf-8' });
+                map = JSON.parse(contents);
+            }
+            catch (e) {
+                map = {};
+            }
+            map[key] = value;
+            fs.writeFileSync(filename, JSON.stringify(map));
+        });
+    }
+    set(key, value) {
+        return __awaiter(this, void 0, void 0, function* () {
+            return yield this.put(key, value);
+        });
+    }
+    getMap() {
+        try {
+            const filename = "data/storage_" + this.prefix;
+            const contents = fs.readFileSync(filename, { encoding: 'utf-8' });
+            return JSON.parse(contents);
+        }
+        catch (e) {
+            return {};
+        }
+    }
+}
+exports.Storage = Storage;
+//# sourceMappingURL=storage.js.map

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
lib/storage.js.map


+ 3 - 0
lib/util.d.ts

@@ -0,0 +1,3 @@
+/// <reference types="node" />
+export declare function toArray(msg: any, enc: any): any[];
+export declare function encodeHex(msg: Buffer | Uint8Array): string;

+ 58 - 0
lib/util.js

@@ -0,0 +1,58 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function zero2(word) {
+    if (word.length === 1) {
+        return '0' + word;
+    }
+    else {
+        return word;
+    }
+}
+function toArray(msg, enc) {
+    if (Array.isArray(msg)) {
+        return msg.slice();
+    }
+    if (!msg) {
+        return [];
+    }
+    const res = [];
+    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;
+}
+exports.toArray = toArray;
+function encodeHex(msg) {
+    let res = '';
+    for (let i = 0; i < msg.length; i++) {
+        res += zero2(msg[i].toString(16));
+    }
+    return res;
+}
+exports.encodeHex = encodeHex;
+//# sourceMappingURL=util.js.map

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
lib/util.js.map


+ 6 - 0
lib/webclient-node.d.ts

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

+ 37 - 0
lib/webclient-node.js

@@ -0,0 +1,37 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const request = require("request-promise");
+class WebClientNode {
+    request(options) {
+        return __awaiter(this, void 0, void 0, function* () {
+            const rpOptions = {
+                method: options.method,
+                uri: options.url
+            };
+            const result = request(rpOptions);
+            return result;
+        });
+    }
+    requestJSON(options) {
+        return __awaiter(this, void 0, void 0, function* () {
+            if (!options.headers) {
+                options.headers = {};
+            }
+            if (options.body) {
+                options.headers['content-type'] = 'application/json';
+            }
+            options.headers.accept = 'application/json';
+            return JSON.parse(yield this.request(options));
+        });
+    }
+}
+exports.default = WebClientNode;
+//# sourceMappingURL=webclient-node.js.map

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
lib/webclient-node.js.map


+ 6 - 0
lib/webclient-options.d.ts

@@ -0,0 +1,6 @@
+export interface IWebClientOptions {
+    method: string;
+    url: string;
+    headers?: any;
+    body?: any;
+}

+ 3 - 0
lib/webclient-options.js

@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=webclient-options.js.map

+ 1 - 0
lib/webclient-options.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"webclient-options.js","sourceRoot":"","sources":["../src/webclient-options.ts"],"names":[],"mappings":""}

+ 5 - 0
lib/webclient.d.ts

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

+ 3 - 0
lib/webclient.js

@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=webclient.js.map

+ 1 - 0
lib/webclient.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"webclient.js","sourceRoot":"","sources":["../src/webclient.ts"],"names":[],"mappings":""}

+ 30 - 11
package-lock.json

@@ -1915,7 +1915,8 @@
         "ansi-regex": {
           "version": "2.1.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -1936,12 +1937,14 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -1956,17 +1959,20 @@
         "code-point-at": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -2083,7 +2089,8 @@
         "inherits": {
           "version": "2.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -2095,6 +2102,7 @@
           "version": "1.0.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -2109,6 +2117,7 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -2116,12 +2125,14 @@
         "minimist": {
           "version": "0.0.8",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -2140,6 +2151,7 @@
           "version": "0.5.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -2220,7 +2232,8 @@
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -2232,6 +2245,7 @@
           "version": "1.4.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -2317,7 +2331,8 @@
         "safe-buffer": {
           "version": "5.1.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -2353,6 +2368,7 @@
           "version": "1.0.2",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -2372,6 +2388,7 @@
           "version": "3.0.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -2415,12 +2432,14 @@
         "wrappy": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },

+ 45 - 45
src/util.ts

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