"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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const crypto = require("libp2p-crypto"); const util = require("util"); const storage_1 = require("./storage"); const TextEncoder = util.TextEncoder; const util_1 = require("./util"); const webclient_node_1 = __importDefault(require("./webclient-node")); class BankClient { constructor(urlBase, storage = new storage_1.Storage('bankClient'), webClient = new webclient_node_1.default()) { 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); }); } 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); }); } 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 = yield this.webClient.requestJSON({ body: retrieveRequest, method: 'POST', url: topicURL }); return postResponse.balance; }); } upload(params) { return __awaiter(this, void 0, void 0, function* () { const url = this.urlBase + '/bank/upload'; const formData = {}; if (params.fileData) { formData.file = { value: params.fileData, options: { filename: params.fileName } }; } if (params.thumbFileData) { formData.thumb = { value: params.thumbFileData, options: { filename: params.thumbFileName } }; } if (params.links) { formData.links = JSON.stringify(params.links); } for (const attr of ['title', 'text', 'type']) { if (params[attr] != null) { formData[attr] = params[attr]; } } const uploadResponse = yield this.webClient.requestJSON({ formData, method: 'POST', url }); return uploadResponse.hash; }); } appendBank(bankLink, itemHash) { return __awaiter(this, void 0, void 0, function* () { const payload = yield this.makePlaintextPayload(itemHash); const { address, topic } = this.parseBankLink(bankLink); const topicURL = this.urlBase + '/bank/private/' + encodeURIComponent(address) + '/' + encodeURIComponent(topic); yield this.webClient.requestJSON({ body: payload, method: 'PUT', url: topicURL }); }); } 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); }); })); })); } parseBankLink(bankLink) { if (!bankLink.startsWith('bank:')) { throw new Error('address must start with bank:'); } const [address, topic] = bankLink.substring(5).split('/'); if (!address || !topic) { throw new Error('cannot parse address and topic'); } return { address, topic }; } } exports.BankClient = BankClient; //# sourceMappingURL=index.js.map