UNPKG

wallet-storage

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

141 lines 6.5 kB
"use strict"; /** * StorageServer.ts * * A server-side class that "has a" local WalletStorage (like a StorageKnex instance), * and exposes it via a JSON-RPC POST endpoint using Express. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StorageServer = void 0; const express_1 = __importDefault(require("express")); const auth_express_middleware_1 = require("@bsv/auth-express-middleware"); const payment_express_middleware_1 = require("@bsv/payment-express-middleware"); const index_all_1 = require("../../index.all"); class StorageServer { constructor(storage, options) { this.app = (0, express_1.default)(); this.storage = storage; this.port = options.port; this.wallet = options.wallet; this.monetize = options.monetize; this.calculateRequestPrice = options.calculateRequestPrice; this.setupRoutes(); } setupRoutes() { this.app.use(express_1.default.json({ limit: '30mb' })); // This allows the API to be used everywhere when CORS is enforced this.app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', '*'); res.header('Access-Control-Allow-Methods', '*'); res.header('Access-Control-Expose-Headers', '*'); res.header('Access-Control-Allow-Private-Network', 'true'); if (req.method === 'OPTIONS') { // Handle CORS preflight requests to allow cross-origin POST/PUT requests res.sendStatus(200); } else { next(); } }); const options = { wallet: this.wallet }; this.app.use((0, auth_express_middleware_1.createAuthMiddleware)(options)); if (this.monetize) { this.app.use((0, payment_express_middleware_1.createPaymentMiddleware)({ wallet: this.wallet, calculateRequestPrice: this.calculateRequestPrice || (() => 100) })); } // A single POST endpoint for JSON-RPC: this.app.post('/', async (req, res) => { let { jsonrpc, method, params, id } = req.body; // Basic JSON-RPC protocol checks: if (jsonrpc !== '2.0' || !method || typeof method !== 'string') { return res.status(400).json({ error: { code: -32600, message: 'Invalid Request' } }); } try { // Dispatch the method call: if (typeof this[method] === 'function') { // if you wanted to handle certain methods on the server class itself // e.g. this['someServerMethod'](params) throw new Error('Server method dispatch not used in this approach.'); } else if (typeof this.storage[method] === 'function') { // method is on the walletStorage: // Find user switch (method) { case 'destroy': { console.log(`StorageServer: method=${method} IGNORED`); return res.json({ jsonrpc: '2.0', result: undefined, id }); } case 'getSettings': { /** */ } break; case 'findOrInsertUser': { if (params[0] !== req.auth.identityKey) throw new index_all_1.sdk.WERR_UNAUTHORIZED('function may only access authenticated user.'); } break; default: { if (typeof params[0] !== 'object' || !params[0]) { params = [{}]; } if (params[0]['identityKey'] && params[0]['identityKey'] !== req.auth.identityKey) throw new index_all_1.sdk.WERR_UNAUTHORIZED('identityKey does not match authentiation'); console.log('looking up user with identityKey:', req.auth.identityKey); const { user, isNew } = await this.storage.findOrInsertUser(req.auth.identityKey); params[0].reqAuthUserId = user.userId; if (params[0]['identityKey']) params[0].userId = user.userId; } break; } console.log(`StorageServer: method=${method} params=${JSON.stringify(params).slice(0, 512)}`); const result = await this.storage[method](...(params || [])); console.log(`StorageServer: method=${method} result=${JSON.stringify(result || 'void').slice(0, 512)}`); return res.json({ jsonrpc: '2.0', result, id }); } else { // Unknown method return res.status(400).json({ jsonrpc: '2.0', error: { code: -32601, message: `Method not found: ${method}` }, id }); } } catch (error) { // Catch any thrown errors from the local walletStorage method const err = error; return res.status(200).json({ jsonrpc: '2.0', error: { code: -32000, message: err.message, data: { name: err.name, stack: err.stack } }, id }); } }); } start() { this.app.listen(this.port, () => { console.log(`WalletStorageServer listening at http://localhost:${this.port}`); }); } } exports.StorageServer = StorageServer; //# sourceMappingURL=StorageServer.js.map