UNPKG

@slide-computer/signer-web

Version:

JavaScript and TypeScript library to communicate with web signers on the Internet Computer

170 lines 8.58 kB
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 _AgentChannel_instances, _AgentChannel_agent, _AgentChannel_closeListeners, _AgentChannel_responseListeners, _AgentChannel_closed, _AgentChannel_createResponse; import { fromBase64, INVALID_REQUEST_ERROR, isJsonRpcRequest, NOT_SUPPORTED_ERROR, toBase64, } from "@slide-computer/signer"; import { AgentTransportError } from "./agentTransport"; import { scopes, supportedStandards } from "./constants"; import { DelegationChain, DelegationIdentity } from "@dfinity/identity"; import { Cbor, HttpAgent, polling } from "@dfinity/agent"; import { Principal } from "@dfinity/principal"; export class AgentChannel { constructor(agent) { _AgentChannel_instances.add(this); _AgentChannel_agent.set(this, void 0); _AgentChannel_closeListeners.set(this, new Set()); _AgentChannel_responseListeners.set(this, new Set()); _AgentChannel_closed.set(this, false); __classPrivateFieldSet(this, _AgentChannel_agent, agent, "f"); } get closed() { return __classPrivateFieldGet(this, _AgentChannel_closed, "f"); } addEventListener(...[event, listener]) { switch (event) { case "close": __classPrivateFieldGet(this, _AgentChannel_closeListeners, "f").add(listener); return () => { __classPrivateFieldGet(this, _AgentChannel_closeListeners, "f").delete(listener); }; case "response": __classPrivateFieldGet(this, _AgentChannel_responseListeners, "f").add(listener); return () => { __classPrivateFieldGet(this, _AgentChannel_responseListeners, "f").delete(listener); }; } } async send(request) { if (this.closed) { throw new AgentTransportError("Communication channel is closed"); } // Ignore one way messages const id = request.id; if (id === undefined) { return; } // Create response and call listeners const response = await __classPrivateFieldGet(this, _AgentChannel_instances, "m", _AgentChannel_createResponse).call(this, Object.assign({ id }, request)); __classPrivateFieldGet(this, _AgentChannel_responseListeners, "f").forEach((listener) => listener(response)); } async close() { __classPrivateFieldSet(this, _AgentChannel_closed, true, "f"); __classPrivateFieldGet(this, _AgentChannel_closeListeners, "f").forEach((listener) => listener()); } } _AgentChannel_agent = new WeakMap(), _AgentChannel_closeListeners = new WeakMap(), _AgentChannel_responseListeners = new WeakMap(), _AgentChannel_closed = new WeakMap(), _AgentChannel_instances = new WeakSet(), _AgentChannel_createResponse = async function _AgentChannel_createResponse(request) { var _a, _b; const id = request.id; if (!isJsonRpcRequest(request)) { return { id, jsonrpc: "2.0", error: { code: INVALID_REQUEST_ERROR, message: "Invalid request" }, }; } switch (request.method) { case "icrc25_supported_standards": return { id, jsonrpc: "2.0", result: { supportedStandards }, }; case "icrc25_permissions": case "icrc25_request_permissions": return { id, jsonrpc: "2.0", result: { scopes }, }; case "icrc27_accounts": const owner = (await __classPrivateFieldGet(this, _AgentChannel_agent, "f").getPrincipal()).toText(); return { id, jsonrpc: "2.0", result: { accounts: [{ owner }], }, }; case "icrc34_delegation": const delegationRequest = request; const identity = __classPrivateFieldGet(this, _AgentChannel_agent, "f").config.identity; const delegationChain = identity instanceof DelegationIdentity ? identity.getDelegation() : undefined; const expiration = new Date(Date.now() + Number(delegationRequest.params.maxTimeToLive ? BigInt(delegationRequest.params.maxTimeToLive) / BigInt(1000000) : BigInt(8) * BigInt(3600000))); const signedDelegationChain = await DelegationChain.create(identity, { toDer: () => fromBase64(delegationRequest.params.publicKey) }, expiration, { previous: delegationChain, targets: (_a = delegationRequest.params.targets) === null || _a === void 0 ? void 0 : _a.map((target) => Principal.fromText(target)), }); return { id, jsonrpc: "2.0", result: { publicKey: toBase64(signedDelegationChain.publicKey), signerDelegation: signedDelegationChain.delegations.map(({ delegation, signature }) => ({ delegation: Object.assign({ pubkey: toBase64(delegation.pubkey), expiration: delegation.expiration.toString() }, (delegation.targets ? { targets: delegation.targets.map((target) => target.toText()), } : {})), signature: toBase64(signature), })), }, }; case "icrc49_call_canister": const callCanisterRequest = request; const { pollForResponse, defaultStrategy } = polling; const canisterId = Principal.fromText(callCanisterRequest.params.canisterId); if (((_b = callCanisterRequest.params) === null || _b === void 0 ? void 0 : _b.sender) !== __classPrivateFieldGet(this, _AgentChannel_agent, "f").getPrincipal().toString()) { throw new AgentTransportError("Sender does not match Agent identity"); } const agent = await HttpAgent.from(__classPrivateFieldGet(this, _AgentChannel_agent, "f")); let contentMap; agent.addTransform("update", async (agentRequest) => { contentMap = Cbor.encode(agentRequest.body); return agentRequest; }); const submitResponse = await agent.call(canisterId, { effectiveCanisterId: canisterId, methodName: callCanisterRequest.params.method, arg: fromBase64(callCanisterRequest.params.arg), }); await pollForResponse(agent, canisterId, submitResponse.requestId, defaultStrategy()); const { certificate } = await agent.readState(canisterId, { paths: [ [ new TextEncoder().encode("request_status"), submitResponse.requestId, ], ], }); return { id, jsonrpc: "2.0", result: { contentMap: toBase64(contentMap), certificate: toBase64(certificate), }, }; default: return { id, jsonrpc: "2.0", error: { code: NOT_SUPPORTED_ERROR, message: "Not supported" }, }; } }; //# sourceMappingURL=agentChannel.js.map