UNPKG

@signumjs/wallets

Version:

Wallets communication package for DApps in the Signum Network

164 lines 6.52 kB
"use strict"; /** * Original work Copyright (c) 2020 Madfish Solutions * Modified work Copyright (c) 2022 Signum Network */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BrowserExtensionAdapter = void 0; const nanoid_1 = require("nanoid"); const messaging_1 = require("./messaging"); const errors_1 = require("./errors"); /** * Extension Adapter for Browser based wallet access, to use with {@link GenericExtensionWallet} * * This adapter is automatically chosen in browser environments - Usually, you won't use this adapter directly. */ class BrowserExtensionAdapter { static send(msg) { window.postMessage(msg, '*'); } static assertResponse(condition) { if (!condition) { throw new Error('Invalid response received'); } } /** * Asserts that a compatible extension wallet is available * @throws Exception if no wallet was found */ async assertWalletAvailable() { return new Promise((resolve, reject) => { const handleMessage = (evt) => { if (evt.source === window && evt.data?.type === messaging_1.PageMessageType.Response && evt.data?.payload === 'PONG') { done(true); } }; const done = (result) => { window.removeEventListener('message', handleMessage); clearTimeout(t); if (result) { resolve(); } else { reject((0, errors_1.createError)(messaging_1.ExtensionErrorType.NotFound)); } }; window.addEventListener('message', handleMessage); BrowserExtensionAdapter.send({ type: messaging_1.PageMessageType.Request, payload: 'PING', }); const t = setTimeout(() => done(false), 1_000); }); } /** * Informs about extension wallet events, like network/node changes, permission and/or account removals * @param callback The callback object with the event handler * @return The listener object, that can/should be used to unsubscribe if not needed anymore */ onNotification(callback) { let listener; function handleMessage(evt) { if (evt.source === window && evt.origin === location.origin && typeof (evt.data.type) === 'string' && evt.data.type.startsWith('XT_DAPP_')) { callback(evt.data); } } window.addEventListener('message', handleMessage); listener = { unlisten: () => { window.removeEventListener('message', handleMessage); } }; return listener; } /** * Gets the current permission * @return The extensions permission object */ async getCurrentPermission() { const res = await this.request({ type: messaging_1.ExtensionMessageType.GetCurrentPermissionRequest, }); BrowserExtensionAdapter.assertResponse(res.type === messaging_1.ExtensionMessageType.GetCurrentPermissionResponse); return res.permission; } /** * Generic request method, to request various operations * @param payload The payload object for the respective operation * @return The response from the wallet in case of success * @throws An error object in case of failures, see also {@link ExtensionWalletError} */ request(payload) { return new Promise((resolve, reject) => { const reqId = (0, nanoid_1.nanoid)(); const handleMessage = (evt) => { const res = evt.data; if (evt.source !== window || res?.reqId !== reqId) { return; } else if (res?.type === messaging_1.PageMessageType.Response) { resolve(res.payload); window.removeEventListener('message', handleMessage); } else if (res?.type === messaging_1.PageMessageType.ErrorResponse) { reject((0, errors_1.createError)(res.payload)); window.removeEventListener('message', handleMessage); } }; BrowserExtensionAdapter.send({ type: messaging_1.PageMessageType.Request, payload, reqId, }); window.addEventListener('message', handleMessage); }); } /** * Requests the permission of a compatible wallet. * A permission is based on _one_ network, e.g. Signum, Signum-TESTNET, etc. and the url of the requesting application. * The wallet should have selected a node of the required network, otherwise permission request fails with {@link InvalidNetworkError} * @param args The argument object */ async requestPermission(args) { const res = await this.request({ type: messaging_1.ExtensionMessageType.PermissionRequest, network: args.network, appMeta: args.appMeta, }); BrowserExtensionAdapter.assertResponse(res.type === messaging_1.ExtensionMessageType.PermissionResponse); return { currentNodeHost: res.currentNodeHost, availableNodeHosts: res.availableNodeHosts, accountId: res.accountId, publicKey: res.publicKey, watchOnly: res.watchOnly }; } async requestSign(args) { const res = await this.request({ type: messaging_1.ExtensionMessageType.SignRequest, payload: args.unsignedTransaction, }); BrowserExtensionAdapter.assertResponse(res.type === messaging_1.ExtensionMessageType.SignResponse); return { transactionId: res.transactionId, fullHash: res.fullHash }; } async requestSendEncryptedMessage(args) { const res = await this.request({ type: messaging_1.ExtensionMessageType.SendEncryptedMessageRequest, ...args }); BrowserExtensionAdapter.assertResponse(res.type === messaging_1.ExtensionMessageType.SendEncryptedMessageResponse); return { transactionId: res.transactionId, fullHash: res.fullHash }; } } exports.BrowserExtensionAdapter = BrowserExtensionAdapter; //# sourceMappingURL=browserExtensionAdapter.js.map