@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
JavaScript
"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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