UNPKG

@zkp2p/reclaim-witness-sdk

Version:

<div> <div> <img src="https://raw.githubusercontent.com/reclaimprotocol/.github/main/assets/banners/Attestor-Core.png" /> </div> </div>

291 lines 23.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupWindowRpc = setupWindowRpc; const tls_1 = require("@reclaimprotocol/tls"); const create_claim_on_avs_1 = require("../avs/client/create-claim-on-avs"); const client_1 = require("../client"); const create_claim_on_mechain_1 = require("../mechain/client/create-claim-on-mechain"); const utils_1 = require("../providers/http/utils"); const utils_2 = require("../utils"); const b64_json_1 = require("../utils/b64-json"); const benchmark_1 = require("../utils/benchmark"); const utils_3 = require("../window-rpc/utils"); const window_rpc_zk_1 = require("../window-rpc/window-rpc-zk"); class WindowRPCEvent extends Event { constructor(data) { super('message'); this.data = data; } } const VALID_MODULES = [ 'attestor-core', 'witness-sdk' ]; let logger = utils_2.logger; /** * Sets up the current window to listen for RPC requests * from React Native or other windows */ function setupWindowRpc() { logger = (0, utils_2.makeLogger)(true); window.addEventListener('message', handleMessage, false); const windowMsgs = new EventTarget(); const defaultUrl = (0, utils_3.getWsApiUrlFromLocation)(); logger.info({ defaultUrl }, 'window RPC setup'); async function handleMessage(event) { let id = ''; let channel = ''; try { if (!event.data) { return; } const req = (typeof event.data === 'string' ? JSON.parse(event.data, b64_json_1.B64_JSON_REVIVER) : event.data); logger.debug({ req, origin: event.origin }, 'recv RPC message'); // ignore any messages not for us if (!VALID_MODULES.includes(req.module)) { return; } id = req.id; channel = req.channel || ''; windowMsgs.dispatchEvent(new WindowRPCEvent(req)); // ignore response messages if (('isResponse' in req && req.isResponse)) { return; } if (!req.id) { logger.warn({ req }, 'Window RPC request missing ID'); return; } logger.info({ req, origin: event.origin }, 'processing RPC request'); switch (req.type) { case 'createClaim': const claimTunnelRes = await (0, client_1.createClaimOnAttestor)({ ...req.request, context: req.request.context ? JSON.parse(req.request.context) : undefined, zkOperators: getZkOperators(req.request.zkOperatorMode, req.request.zkEngine), oprfOperators: getOprfOperators(req.request.zkOperatorMode, req.request.zkEngine), client: { url: defaultUrl, authRequest: req.request.authRequest }, logger, onStep(step) { sendMessage({ type: 'createClaimStep', step: { name: req.module.includes('witness') // backwards compatibility ? 'witness-progress' : 'attestor-progress', step, }, module: req.module, id: req.id, }); }, updateProviderParams: req.request.updateProviderParams ? updateProviderParams : undefined }); const response = (0, utils_3.mapToCreateClaimResponse)(claimTunnelRes); respond({ type: 'createClaimDone', response, }); break; case 'createClaimOnAvs': const avsRes = await (0, create_claim_on_avs_1.createClaimOnAvs)({ ...req.request, payer: req.request.payer === 'attestor' ? { attestor: defaultUrl } : undefined, context: req.request.context ? JSON.parse(req.request.context) : undefined, zkOperators: getZkOperators(req.request.zkOperatorMode, req.request.zkEngine), oprfOperators: getOprfOperators(req.request.zkOperatorMode, req.request.zkEngine), logger, onStep(step) { sendMessage({ type: 'createClaimOnAvsStep', step, module: req.module, id: req.id, }); }, }); respond({ type: 'createClaimOnAvsDone', response: avsRes, }); break; case 'createClaimOnMechain': const mechainRes = await (0, create_claim_on_mechain_1.createClaimOnMechain)({ ...req.request, context: req.request.context ? JSON.parse(req.request.context) : undefined, zkOperators: getZkOperators(req.request.zkOperatorMode, req.request.zkEngine), oprfOperators: getOprfOperators(req.request.zkOperatorMode, req.request.zkEngine), client: { url: defaultUrl, }, logger, onStep(step) { sendMessage({ type: 'createClaimOnMechainStep', step, module: req.module, id: req.id, }); }, }); const claimResponses = []; for (let i = 0; i < mechainRes.responses.length; i++) { claimResponses[i] = (0, utils_3.mapToCreateClaimResponse)(mechainRes.responses[i]); } respond({ type: 'createClaimOnMechainDone', response: { taskId: mechainRes.taskId, data: claimResponses }, }); break; case 'extractHtmlElement': respond({ type: 'extractHtmlElementDone', response: (0, utils_1.extractHTMLElement)(req.request.html, req.request.xpathExpression, req.request.contentsOnly), }); break; case 'extractJSONValueIndex': respond({ type: 'extractJSONValueIndexDone', response: (0, utils_1.extractJSONValueIndex)(req.request.json, req.request.jsonPath), }); break; case 'getCurrentMemoryUsage': respond({ type: 'getCurrentMemoryUsageDone', response: await (0, utils_3.getCurrentMemoryUsage)(), }); break; case 'setLogLevel': logger = (0, utils_2.makeLogger)(true, req.request.logLevel, req.request.sendLogsToApp ? (level, message) => (sendMessage({ type: 'log', level, message, module: req.module, id: req.id, })) : undefined); respond({ type: 'setLogLevelDone', response: undefined }); break; case 'benchmarkZK': respond({ type: 'benchmarkZKDone', response: await (0, benchmark_1.Benchmark)(), }); break; default: break; } } catch (err) { logger.error({ msg: err.message, err, data: event.data }, 'error in RPC'); respond({ type: 'error', data: { message: err.message, stack: err.stack, } }); } function getZkOperators(mode = 'default', zkEngine = 'snarkjs') { // use default snarkJS ops if (mode === 'default') { return; } // the native app/window calling implements // a ZK operator & wants to use it const operators = {}; for (const alg of window_rpc_zk_1.ALL_ENC_ALGORITHMS) { operators[alg] = (0, window_rpc_zk_1.makeWindowRpcZkOperator)(alg, makeCommunicationBridge(), zkEngine); } return operators; } function getOprfOperators(mode = 'default', zkEngine = 'snarkjs') { // use default webview ops if (mode === 'default') { return; } // the native app/window calling implements // a ZK operator & wants to use it const operators = {}; for (const alg of window_rpc_zk_1.ALL_ENC_ALGORITHMS) { operators[alg] = (0, window_rpc_zk_1.makeWindowRpcOprfOperator)(alg, makeCommunicationBridge(), zkEngine); } return operators; } function makeCommunicationBridge() { return { send: sendMessage, onMessage(cb) { windowMsgs.addEventListener('message', handle); return () => { windowMsgs.removeEventListener('message', handle); }; function handle(msg) { cb(msg.data); } }, }; } function respond(data) { const res = { ...data, id, module: 'attestor-core', isResponse: true }; return sendMessage(res); } function sendMessage(data) { var _a; const str = JSON.stringify(data, b64_json_1.B64_JSON_REPLACER); if (channel) { (_a = window[channel]) === null || _a === void 0 ? void 0 : _a.postMessage(str); } else { event.source.postMessage(str); } } async function updateProviderParams(transcript, tlsVersion) { const { req, res } = (0, utils_1.generateRequstAndResponseFromTranscript)(transcript, tlsVersion); const bridge = makeCommunicationBridge(); const id = (0, utils_3.generateRpcRequestId)(); const waitForRes = (0, utils_3.waitForResponse)('updateProviderParams', id, bridge); bridge.send({ type: 'updateProviderParams', id, request: { request: { ...req, body: req.body ? (0, tls_1.uint8ArrayToStr)(req.body) : undefined }, response: { ...res, body: (0, tls_1.uint8ArrayToStr)(res.body) }, }, module: 'attestor-core' }); return await waitForRes; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXAtd2luZG93LXJwYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93aW5kb3ctcnBjL3NldHVwLXdpbmRvdy1ycGMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUErQkEsd0NBMlZDO0FBMVhELDhDQUFzRDtBQUV0RCw0RUFBcUU7QUFDckUsdUNBQWtEO0FBQ2xELHdGQUFpRjtBQUNqRixvREFBNkg7QUFFN0gscUNBQXdEO0FBQ3hELGlEQUF3RTtBQUN4RSxtREFBK0M7QUFFL0MsZ0RBQXNKO0FBQ3RKLGdFQUFxSDtBQUVySCxNQUFNLGNBQWUsU0FBUSxLQUFLO0lBQ2pDLFlBQTRCLElBQTBCO1FBQ3JELEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQURXLFNBQUksR0FBSixJQUFJLENBQXNCO0lBRXRELENBQUM7Q0FDRDtBQUVELE1BQU0sYUFBYSxHQUFHO0lBQ3JCLGVBQWU7SUFDZixhQUFhO0NBQ2IsQ0FBQTtBQUVELElBQUksTUFBTSxHQUFHLGNBQU0sQ0FBQTtBQUVuQjs7O0dBR0c7QUFDSCxTQUFnQixjQUFjO0lBQzdCLE1BQU0sR0FBRyxJQUFBLGtCQUFVLEVBQUMsSUFBSSxDQUFDLENBQUE7SUFFekIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFDeEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQTtJQUVwQyxNQUFNLFVBQVUsR0FBRyxJQUFBLCtCQUF1QixHQUFFLENBQUE7SUFFNUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLGtCQUFrQixDQUFDLENBQUE7SUFFL0MsS0FBSyxVQUFVLGFBQWEsQ0FBQyxLQUF3QjtRQUNwRCxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUE7UUFDWCxJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUE7UUFDaEIsSUFBSSxDQUFDO1lBQ0osSUFBRyxDQUFDLEtBQUssQ0FBQyxJ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