@metamask/kernel-rpc-methods
Version:
Utilities for implementing Ocap Kernel JSON-RPC methods
100 lines • 4.85 kB
JavaScript
;
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _RpcService_instances, _RpcService_handlers, _RpcService_hooks, _RpcService_hasMethod, _RpcService_getHandler;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcService = void 0;
const rpc_errors_1 = require("@metamask/rpc-errors");
const utils_1 = require("@metamask/utils");
/**
* A registry for RPC method handlers that provides type-safe registration and execution.
*/
class RpcService {
/**
* Create a new HandlerRegistry with the specified method handlers.
*
* @param handlers - A record mapping method names to their handler implementations.
* @param hooks - The hooks to pass to the method implementation.
*/
constructor(handlers, hooks) {
_RpcService_instances.add(this);
_RpcService_handlers.set(this, void 0);
_RpcService_hooks.set(this, void 0);
__classPrivateFieldSet(this, _RpcService_handlers, handlers, "f");
__classPrivateFieldSet(this, _RpcService_hooks, hooks, "f");
}
/**
* Assert that a method is registered in this registry.
*
* @param method - The method name to check.
* @throws If the method is not registered.
*/
assertHasMethod(method) {
if (!__classPrivateFieldGet(this, _RpcService_instances, "m", _RpcService_hasMethod).call(this, method)) {
throw rpc_errors_1.rpcErrors.methodNotFound();
}
}
/**
* Execute a method with the provided parameters. Only the hooks specified in the
* handler's `hooks` array will be passed to the implementation.
*
* @param method - The method name to execute.
* @param params - The parameters to pass to the method implementation.
* @returns The result of the method execution.
* @throws If the parameters are invalid.
*/
async execute(method, params) {
const handler = __classPrivateFieldGet(this, _RpcService_instances, "m", _RpcService_getHandler).call(this, method);
assertParams(params, handler.params);
const expectedHooks = selectHooks(__classPrivateFieldGet(this, _RpcService_hooks, "f"), handler.hooks);
return await handler.implementation(expectedHooks, params);
}
}
exports.RpcService = RpcService;
_RpcService_handlers = new WeakMap(), _RpcService_hooks = new WeakMap(), _RpcService_instances = new WeakSet(), _RpcService_hasMethod = function _RpcService_hasMethod(method) {
return (0, utils_1.hasProperty)(__classPrivateFieldGet(this, _RpcService_handlers, "f"), method);
}, _RpcService_getHandler = function _RpcService_getHandler(method) {
return __classPrivateFieldGet(this, _RpcService_handlers, "f")[method];
};
/**
* @param params - The parameters to assert.
* @param struct - The struct to assert the parameters against.
* @throws If the parameters are invalid.
*/
function assertParams(params, struct) {
try {
struct.assert(params);
}
catch (error) {
throw new Error(`Invalid params: ${error.message}`);
}
}
/**
* Returns the subset of the specified `hooks` that are included in the
* `hookNames` array. This is a Principle of Least Authority (POLA) measure
* to ensure that each RPC method implementation only has access to the
* API "hooks" it needs to do its job.
*
* @param hooks - The hooks to select from.
* @param hookNames - The names of the hooks to select.
* @returns The selected hooks.
* @template Hooks - The hooks to select from.
* @template HookName - The names of the hooks to select.
*/
function selectHooks(hooks, hookNames) {
return Object.keys(hookNames).reduce((hookSubset, hookName) => {
const key = hookName;
hookSubset[key] = hooks[key];
return hookSubset;
}, {});
}
//# sourceMappingURL=RpcService.cjs.map