wallet-storage
Version:
BRC100 conforming wallet, wallet storage and wallet signer components
141 lines • 6.5 kB
JavaScript
;
/**
* 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