@airgap/beacon-dapp
Version:
Use this package on your dApp to instanciate a DAppClient object and communicate to wallets.
703 lines • 27.7 kB
JavaScript
import { closeAlert, openAlert, openBugReport, closeToast, openToast } from '@airgap/beacon-dapp';
import { BeaconErrorType } from '@airgap/beacon-types';
import { UnknownBeaconError, Logger, getError
// EncryptPayloadResponseOutput,
// EncryptionOperation
} from '@airgap/beacon-core';
import { shortenString } from './utils/shorten-string';
import { isMobile, isMobileOS } from '@airgap/beacon-ui';
const logger = new Logger('BeaconEvents');
const SUCCESS_TIMER = 5 * 1000;
/**
* The different events that can be emitted by the beacon-sdk
*/
export var BeaconEvent;
(function (BeaconEvent) {
BeaconEvent["PERMISSION_REQUEST_SENT"] = "PERMISSION_REQUEST_SENT";
BeaconEvent["PERMISSION_REQUEST_SUCCESS"] = "PERMISSION_REQUEST_SUCCESS";
BeaconEvent["PERMISSION_REQUEST_ERROR"] = "PERMISSION_REQUEST_ERROR";
BeaconEvent["PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT"] = "PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT";
BeaconEvent["PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS"] = "PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS";
BeaconEvent["PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR"] = "PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR";
BeaconEvent["SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT"] = "SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT";
BeaconEvent["SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS"] = "SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS";
BeaconEvent["SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR"] = "SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR";
BeaconEvent["OPERATION_REQUEST_SENT"] = "OPERATION_REQUEST_SENT";
BeaconEvent["OPERATION_REQUEST_SUCCESS"] = "OPERATION_REQUEST_SUCCESS";
BeaconEvent["OPERATION_REQUEST_ERROR"] = "OPERATION_REQUEST_ERROR";
BeaconEvent["SIGN_REQUEST_SENT"] = "SIGN_REQUEST_SENT";
BeaconEvent["SIGN_REQUEST_SUCCESS"] = "SIGN_REQUEST_SUCCESS";
BeaconEvent["SIGN_REQUEST_ERROR"] = "SIGN_REQUEST_ERROR";
BeaconEvent["BLOCKCHAIN_REQUEST_SUCCESS"] = "BLOCKCHAIN_REQUEST_SUCCESS";
// TODO: ENCRYPTION
// ENCRYPT_REQUEST_SENT = 'ENCRYPT_REQUEST_SENT',
// ENCRYPT_REQUEST_SUCCESS = 'ENCRYPT_REQUEST_SUCCESS',
// ENCRYPT_REQUEST_ERROR = 'ENCRYPT_REQUEST_ERROR',
BeaconEvent["BROADCAST_REQUEST_SENT"] = "BROADCAST_REQUEST_SENT";
BeaconEvent["BROADCAST_REQUEST_SUCCESS"] = "BROADCAST_REQUEST_SUCCESS";
BeaconEvent["BROADCAST_REQUEST_ERROR"] = "BROADCAST_REQUEST_ERROR";
BeaconEvent["ACKNOWLEDGE_RECEIVED"] = "ACKNOWLEDGE_RECEIVED";
BeaconEvent["LOCAL_RATE_LIMIT_REACHED"] = "LOCAL_RATE_LIMIT_REACHED";
BeaconEvent["NO_PERMISSIONS"] = "NO_PERMISSIONS";
BeaconEvent["ACTIVE_ACCOUNT_SET"] = "ACTIVE_ACCOUNT_SET";
BeaconEvent["ACTIVE_TRANSPORT_SET"] = "ACTIVE_TRANSPORT_SET";
BeaconEvent["SHOW_PREPARE"] = "SHOW_PREPARE";
BeaconEvent["HIDE_UI"] = "HIDE_UI";
BeaconEvent["INVALID_ACTIVE_ACCOUNT_STATE"] = "INVALID_ACTIVE_ACCOUNT_STATE";
BeaconEvent["INVALID_ACCOUNT_DEACTIVATED"] = "INVALID_ACCOUNT_DEACTIVATED";
BeaconEvent["PAIR_INIT"] = "PAIR_INIT";
BeaconEvent["PAIR_SUCCESS"] = "PAIR_SUCCESS";
BeaconEvent["CHANNEL_CLOSED"] = "CHANNEL_CLOSED";
BeaconEvent["GENERIC_ERROR"] = "GENERIC_ERROR";
BeaconEvent["OPEN_BUG_REPORT"] = "OPEN_BUG_REPORT";
BeaconEvent["RELAYER_ERROR"] = "RELAYER_ERROR";
BeaconEvent["INTERNAL_ERROR"] = "INTERNAL_ERROR";
BeaconEvent["UNKNOWN"] = "UNKNOWN";
})(BeaconEvent || (BeaconEvent = {}));
/**
* Show a "Request sent" toast
*/
const showSentToast = async (data) => {
let openWalletAction;
const actions = [];
if (data.walletInfo.deeplink) {
if (data.walletInfo.type === 'web' ||
(data.walletInfo.type === 'mobile' && isMobile(window)) ||
(data.walletInfo.type === 'desktop' && !isMobile(window))) {
const link = data.walletInfo.deeplink;
openWalletAction = async () => {
const a = document.createElement('a');
a.setAttribute('rel', 'noopener');
a.setAttribute('href', link);
a.setAttribute('target', '_blank');
a.dispatchEvent(new MouseEvent('click', { view: window, bubbles: true, cancelable: true }));
};
}
}
actions.push({
text: `No answer from your wallet received yet. Please make sure the wallet is open.`,
isBold: true
});
actions.push({
text: 'Wallet not receiving request?',
actionText: 'Reset Connection',
actionCallback: async () => {
closeToast();
// eslint-disable-next-line @typescript-eslint/unbound-method
const resetCallback = data.extraInfo.resetCallback;
if (resetCallback) {
logger.log('showSentToast', 'resetCallback invoked');
await resetCallback();
}
}
});
actions.push({
text: 'Do you wish to report a bug?',
actionText: 'Open',
actionCallback: async () => {
closeToast();
openBugReport();
}
});
openToast({
body: `Request sent to\u00A0 {{wallet}}`,
walletInfo: data.walletInfo,
state: 'loading',
timer: isMobileOS(window) ? SUCCESS_TIMER : 0,
actions,
openWalletAction
});
};
const showAcknowledgedToast = async (data) => {
openToast({
body: 'Awaiting confirmation in\u00A0 {{wallet}}',
state: 'acknowledge',
walletInfo: data.walletInfo
});
};
const showPrepare = async (data) => {
const text = data.walletInfo
? `Preparing Request for\u00A0 {{wallet}}...`
: 'Preparing Request...';
openToast({
body: text,
state: 'prepare',
walletInfo: data.walletInfo
});
};
const hideUI = (elements) => {
if (elements?.includes('alert')) {
closeAlert();
}
if (elements?.includes('toast') || !elements) {
closeToast();
}
};
/**
* Show a "No Permission" alert
*/
const showNoPermissionAlert = async () => {
openAlert({
title: 'No Permission',
body: 'Please allow the wallet to handle this type of request.'
});
};
/**
* Show an "Invalid state" alert
*/
const showInvalidActiveAccountState = async () => {
openAlert({
title: 'Invalid state',
body: `An active account has been received, but no active subscription was found for BeaconEvent.ACTIVE_ACCOUNT_SET.
For more information, visit: https://docs.walletbeacon.io/guides/migration-guide`
});
};
/**
* Show an "account deactivated" error alert
*/
const showInvalidAccountDeactivated = async () => {
await openAlert({
title: 'Error',
body: `Your session has expired. Please pair with your wallet again.`
});
};
/**
* Show an "Invalid state" alert
*/
const showGenericErrorAlert = async (errorMessage) => {
openAlert({
title: `${errorMessage}`,
body: 'Please try again. If this problem persists please send us a bug report.',
buttons: [
{
label: 'Send Report',
type: 'primary',
onClick: () => openBugReport()
}
]
});
};
/**
* Show an error toast
*
* @param beaconError The beacon error
*/
const showErrorToast = async (response, buttons) => {
const error = response.errorResponse.errorType
? getError(response.errorResponse.errorType, response.errorResponse.errorData)
: new UnknownBeaconError();
const actions = [
{
text: error.title,
isBold: true
}
];
if (response.errorResponse.errorType === BeaconErrorType.TRANSACTION_INVALID_ERROR &&
response.errorResponse.errorData) {
const err = response.errorResponse.errorData;
const errorMessages = response.errorMessages;
let hasHumandReadableError = false;
if (err[0]?.contract_handle && errorMessages && errorMessages?.[err[0].contract_handle]) {
const errCode = err[1]?.with?.int ?? err[1]?.with?.string;
const contractErrors = errorMessages?.[err[0].contract_handle];
if (errCode && contractErrors?.[errCode]) {
actions.push({
text: contractErrors?.[errCode],
isBold: true
});
hasHumandReadableError = true;
}
}
if (!hasHumandReadableError) {
actions.push({
text: error.description
});
}
actions.push({
text: '',
actionText: 'Show Details',
actionCallback: async () => {
closeToast();
openAlert({
title: error.title,
// eslint-disable-next-line @typescript-eslint/unbound-method
body: error.fullDescription.description,
data: error.fullDescription.data,
buttons
});
}
});
}
openToast({
body: `{{wallet}}\u00A0 has returned an error`,
timer: response.errorResponse.errorType === BeaconErrorType.ABORTED_ERROR
? SUCCESS_TIMER
: undefined,
state: 'finished',
walletInfo: response.walletInfo,
actions
});
};
/**
* Show a rate limit reached toast
*/
const showRateLimitReached = async () => {
openAlert({
title: 'Error',
body: 'Rate limit reached. Please slow down',
buttons: [{ text: 'Done', style: 'outline' }],
timer: 3000
});
};
/**
* Show a "connection successful" alert for 1.5 seconds
*/
const showExtensionConnectedAlert = () => {
closeAlert();
};
const showBugReportForm = async () => {
await openBugReport();
};
const showRelayerErrorAlert = async () => {
openAlert({
title: 'Error',
body: `Failed to connect to the relayer. Please check that your system time is synchronized with the current time and reload the page.`,
buttons: [{ text: 'Done', style: 'outline' }],
timer: 1500
});
};
/**
* Show a "channel closed" alert for 1.5 seconds
*/
const showChannelClosedAlert = async () => {
// openAlert({
// title: 'Channel closed',
// body: `Your peer has closed the connection.`,
// buttons: [{ text: 'Done', style: 'outline' }],
// timer: 1500
// })
};
const showInternalErrorAlert = async (data) => {
const buttons = [...(data.buttons ?? [])];
buttons.push({ text: 'Done', style: 'outline' });
const alertConfig = {
title: 'Internal Error',
body: data.text,
buttons
};
openAlert(alertConfig);
};
/**
* Show a connect alert with QR code
*
* @param data The data that is emitted by the PAIR_INIT event
*/
const showPairAlert = async (data) => {
logger.log('showPairAlert');
const alertConfig = {
title: 'Choose your preferred wallet',
body: `<p></p>`,
pairingPayload: {
p2pSyncCode: data.p2pPeerInfo,
walletConnectSyncCode: data.walletConnectPeerInfo,
postmessageSyncCode: data.postmessagePeerInfo,
networkType: data.networkType
},
// eslint-disable-next-line @typescript-eslint/unbound-method
closeButtonCallback: data.abortedHandler,
disclaimerText: data.disclaimerText,
analytics: data.analytics,
featuredWallets: data.featuredWallets,
substratePairing: data.substratePairing
};
openAlert(alertConfig);
};
/**
* Show a "Permission Granted" alert
*
* @param data The data that is emitted by the PERMISSION_REQUEST_SUCCESS event
*/
const showPermissionSuccessAlert = async (data) => {
const { output } = data;
const actions = [
{
text: 'Address',
actionText: shortenString(output.address),
isBold: true
}
];
if (output.network.type !== 'substrate') {
actions.push({
text: 'Network',
actionText: `${output.network.type}`
});
actions.push({
text: 'Permissions',
actionText: output.scopes.join(', ')
});
}
openToast({
body: `{{wallet}}\u00A0 has granted permission`,
timer: SUCCESS_TIMER,
walletInfo: data.walletInfo,
state: 'finished',
actions
});
};
const showProofOfEventChallengeSuccessAlert = async (data) => {
const { output } = data;
openToast({
body: `{{wallet}}\u00A0 has ${output.isAccepted ? 'accepted' : 'refused'} the challenge`,
timer: SUCCESS_TIMER,
walletInfo: data.walletInfo,
state: 'finished',
actions: output.isAccepted
? [
{
text: `Payload hash: ${output.payloadHash}`,
actionText: 'Copy to clipboard',
actionCallback: async () => {
navigator.clipboard.writeText(output.payloadHash).then(() => {
logger.log('showSignSuccessAlert', 'Copying to clipboard was successful!');
}, (err) => {
logger.error('showSignSuccessAlert', 'Could not copy text to clipboard: ', err);
});
closeToast();
}
}
]
: []
});
};
const showSimulatedProofOfEventChallengeSuccessAlert = async (data) => {
const { output } = data;
openToast({
body: !output.errorMessage
? `{{wallet}}\u00A0 has returned the list of operation`
: `{{wallet}}\u00A0 has returned an error`,
timer: SUCCESS_TIMER,
walletInfo: data.walletInfo,
state: 'finished',
actions: !output.errorMessage
? [
{
text: 'Operation list',
actionText: 'Copy to clipboard',
actionCallback: async () => {
navigator.clipboard.writeText(output.operationsList).then(() => {
logger.log('showSignSuccessAlert', 'Copying to clipboard was successful!');
}, (err) => {
logger.error('showSignSuccessAlert', 'Could not copy text to clipboard: ', err);
});
closeToast();
}
}
]
: [{ text: 'Error message', actionText: output.errorMessage }]
});
};
/**
* Show an "Operation Broadcasted" alert
*
* @param data The data that is emitted by the OPERATION_REQUEST_SUCCESS event
*/
const showOperationSuccessAlert = async (data) => {
const { account, output, blockExplorer } = data;
openToast({
body: `{{wallet}}\u00A0 successfully submitted operation`,
timer: SUCCESS_TIMER,
state: 'finished',
walletInfo: data.walletInfo,
actions: [
{
text: shortenString(output.transactionHash),
isBold: true,
actionText: `Open Blockexplorer`,
actionLogo: 'external',
actionCallback: async () => {
const link = await blockExplorer.getTransactionLink(output.transactionHash, account.network);
window.open(link, '_blank', 'noopener');
closeToast();
}
}
]
});
};
/**
* Show a "Transaction Signed" alert
*
* @param data The data that is emitted by the SIGN_REQUEST_SUCCESS event
*/
const showSignSuccessAlert = async (data) => {
const output = data.output;
openToast({
body: `{{wallet}}\u00A0 successfully signed payload`,
timer: SUCCESS_TIMER,
state: 'finished',
walletInfo: data.walletInfo,
actions: [
{
text: `Signature: ${shortenString(output.signature)}`,
actionText: 'Copy to clipboard',
actionCallback: async () => {
navigator.clipboard.writeText(output.signature).then(() => {
logger.log('showSignSuccessAlert', 'Copying to clipboard was successful!');
}, (err) => {
logger.error('showSignSuccessAlert', 'Could not copy text to clipboard: ', err);
});
closeToast();
}
}
]
});
};
/**
* Show a "Transaction Signed" alert
*
* @param data The data that is emitted by the ENCRYPT_REQUEST_SUCCESS event
*/
// TODO: ENCRYPTION
// const showEncryptSuccessAlert = async (
// data: BeaconEventType[BeaconEvent.ENCRYPT_REQUEST_SUCCESS]
// ): Promise<void> => {
// const output = data.output
// openToast({
// body: `{{wallet}}\u00A0 successfully ${
// data.output.cryptoOperation === EncryptionOperation.ENCRYPT ? 'encrypted' : 'decrypted'
// } payload`,
// timer: SUCCESS_TIMER,
// state: 'finished',
// walletInfo: data.walletInfo,
// actions: [
// {
// text: `Payload: <strong>${shortenString(output.payload)}</strong>`,
// actionText: 'Copy to clipboard',
// actionCallback: async (): Promise<void> => {
// navigator.clipboard.writeText(output.payload).then(
// () => {
// logger.log('showSignSuccessAlert', 'Copying to clipboard was successful!')
// },
// (err) => {
// logger.error('showSignSuccessAlert', 'Could not copy text to clipboard: ', err)
// }
// )
// closeToast()
// }
// }
// ]
// })
// }
const showBlockchainRequestSuccessToast = async (data) => {
openToast({
body: `{{wallet}}\u00A0 request successfully executed`,
timer: SUCCESS_TIMER,
state: 'finished',
walletInfo: data.walletInfo
});
};
/**
* Show a "Broadcasted" alert
*
* @param data The data that is emitted by the BROADCAST_REQUEST_SUCCESS event
*/
const showBroadcastSuccessAlert = async (data) => {
const { network, output, blockExplorer } = data;
openToast({
body: `{{wallet}}\u00A0 successfully injected operation`,
timer: SUCCESS_TIMER,
state: 'finished',
walletInfo: data.walletInfo,
actions: [
{
text: shortenString(output.transactionHash),
isBold: true,
actionText: `Open Blockexplorer`,
actionLogo: 'external',
actionCallback: async () => {
const link = await blockExplorer.getTransactionLink(output.transactionHash, network);
window.open(link, '_blank', 'noopener');
closeToast();
}
}
]
});
};
const emptyHandler = () => async () => {
//
};
/**
* The default event handlers
*/
export const defaultEventCallbacks = {
[BeaconEvent.PERMISSION_REQUEST_SENT]: showSentToast,
[BeaconEvent.PERMISSION_REQUEST_SUCCESS]: showPermissionSuccessAlert,
[BeaconEvent.PERMISSION_REQUEST_ERROR]: showErrorToast,
[BeaconEvent.PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT]: showSentToast,
[BeaconEvent.PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS]: showProofOfEventChallengeSuccessAlert,
[BeaconEvent.PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR]: showErrorToast,
[BeaconEvent.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT]: showSentToast,
[BeaconEvent.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS]: showSimulatedProofOfEventChallengeSuccessAlert,
[BeaconEvent.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR]: showErrorToast,
[BeaconEvent.OPERATION_REQUEST_SENT]: showSentToast,
[BeaconEvent.OPERATION_REQUEST_SUCCESS]: showOperationSuccessAlert,
[BeaconEvent.OPERATION_REQUEST_ERROR]: showErrorToast,
[BeaconEvent.SIGN_REQUEST_SENT]: showSentToast,
[BeaconEvent.SIGN_REQUEST_SUCCESS]: showSignSuccessAlert,
[BeaconEvent.SIGN_REQUEST_ERROR]: showErrorToast,
// TODO: ENCRYPTION
// [BeaconEvent.ENCRYPT_REQUEST_SENT]: showSentToast,
// [BeaconEvent.ENCRYPT_REQUEST_SUCCESS]: showEncryptSuccessAlert,
// [BeaconEvent.ENCRYPT_REQUEST_ERROR]: showErrorToast,
[BeaconEvent.BROADCAST_REQUEST_SENT]: showSentToast,
[BeaconEvent.BROADCAST_REQUEST_SUCCESS]: showBroadcastSuccessAlert,
[BeaconEvent.BROADCAST_REQUEST_ERROR]: showErrorToast,
[BeaconEvent.ACKNOWLEDGE_RECEIVED]: showAcknowledgedToast,
[BeaconEvent.LOCAL_RATE_LIMIT_REACHED]: showRateLimitReached,
[BeaconEvent.NO_PERMISSIONS]: showNoPermissionAlert,
[BeaconEvent.ACTIVE_ACCOUNT_SET]: emptyHandler(),
[BeaconEvent.ACTIVE_TRANSPORT_SET]: emptyHandler(),
[BeaconEvent.INVALID_ACTIVE_ACCOUNT_STATE]: showInvalidActiveAccountState,
[BeaconEvent.GENERIC_ERROR]: showGenericErrorAlert,
[BeaconEvent.INVALID_ACCOUNT_DEACTIVATED]: showInvalidAccountDeactivated,
[BeaconEvent.SHOW_PREPARE]: showPrepare,
[BeaconEvent.HIDE_UI]: hideUI,
[BeaconEvent.PAIR_INIT]: showPairAlert,
[BeaconEvent.PAIR_SUCCESS]: showExtensionConnectedAlert,
[BeaconEvent.OPEN_BUG_REPORT]: showBugReportForm,
[BeaconEvent.RELAYER_ERROR]: showRelayerErrorAlert,
[BeaconEvent.CHANNEL_CLOSED]: showChannelClosedAlert,
[BeaconEvent.INTERNAL_ERROR]: showInternalErrorAlert,
[BeaconEvent.BLOCKCHAIN_REQUEST_SUCCESS]: showBlockchainRequestSuccessToast,
[BeaconEvent.UNKNOWN]: emptyHandler()
};
/**
* @internalapi
*
* Handles beacon events
*/
export class BeaconEventHandler {
callbackMap = {
[BeaconEvent.PERMISSION_REQUEST_SENT]: [defaultEventCallbacks.PERMISSION_REQUEST_SENT],
[BeaconEvent.PERMISSION_REQUEST_SUCCESS]: [defaultEventCallbacks.PERMISSION_REQUEST_SUCCESS],
[BeaconEvent.PERMISSION_REQUEST_ERROR]: [defaultEventCallbacks.PERMISSION_REQUEST_ERROR],
[BeaconEvent.PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT]: [
defaultEventCallbacks.PERMISSION_REQUEST_SENT
],
[BeaconEvent.PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS]: [
defaultEventCallbacks.PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS
],
[BeaconEvent.PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR]: [
defaultEventCallbacks.PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR
],
[BeaconEvent.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT]: [
defaultEventCallbacks.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SENT
],
[BeaconEvent.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS]: [
defaultEventCallbacks.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_SUCCESS
],
[BeaconEvent.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR]: [
defaultEventCallbacks.SIMULATED_PROOF_OF_EVENT_CHALLENGE_REQUEST_ERROR
],
[BeaconEvent.OPERATION_REQUEST_SENT]: [defaultEventCallbacks.OPERATION_REQUEST_SENT],
[BeaconEvent.OPERATION_REQUEST_SUCCESS]: [defaultEventCallbacks.OPERATION_REQUEST_SUCCESS],
[BeaconEvent.OPERATION_REQUEST_ERROR]: [defaultEventCallbacks.OPERATION_REQUEST_ERROR],
[BeaconEvent.SIGN_REQUEST_SENT]: [defaultEventCallbacks.SIGN_REQUEST_SENT],
[BeaconEvent.SIGN_REQUEST_SUCCESS]: [defaultEventCallbacks.SIGN_REQUEST_SUCCESS],
[BeaconEvent.SIGN_REQUEST_ERROR]: [defaultEventCallbacks.SIGN_REQUEST_ERROR],
// TODO: ENCRYPTION
// [BeaconEvent.ENCRYPT_REQUEST_SENT]: [defaultEventCallbacks.ENCRYPT_REQUEST_SENT],
// [BeaconEvent.ENCRYPT_REQUEST_SUCCESS]: [defaultEventCallbacks.ENCRYPT_REQUEST_SUCCESS],
// [BeaconEvent.ENCRYPT_REQUEST_ERROR]: [defaultEventCallbacks.ENCRYPT_REQUEST_ERROR],
[BeaconEvent.BROADCAST_REQUEST_SENT]: [defaultEventCallbacks.BROADCAST_REQUEST_SENT],
[BeaconEvent.BROADCAST_REQUEST_SUCCESS]: [defaultEventCallbacks.BROADCAST_REQUEST_SUCCESS],
[BeaconEvent.BROADCAST_REQUEST_ERROR]: [defaultEventCallbacks.BROADCAST_REQUEST_ERROR],
[BeaconEvent.BLOCKCHAIN_REQUEST_SUCCESS]: [defaultEventCallbacks.BLOCKCHAIN_REQUEST_SUCCESS],
[BeaconEvent.ACKNOWLEDGE_RECEIVED]: [defaultEventCallbacks.ACKNOWLEDGE_RECEIVED],
[BeaconEvent.LOCAL_RATE_LIMIT_REACHED]: [defaultEventCallbacks.LOCAL_RATE_LIMIT_REACHED],
[BeaconEvent.NO_PERMISSIONS]: [defaultEventCallbacks.NO_PERMISSIONS],
[BeaconEvent.ACTIVE_ACCOUNT_SET]: [defaultEventCallbacks.ACTIVE_ACCOUNT_SET],
[BeaconEvent.ACTIVE_TRANSPORT_SET]: [defaultEventCallbacks.ACTIVE_TRANSPORT_SET],
[BeaconEvent.INVALID_ACTIVE_ACCOUNT_STATE]: [
defaultEventCallbacks.INVALID_ACTIVE_ACCOUNT_STATE
],
[BeaconEvent.GENERIC_ERROR]: [showGenericErrorAlert],
[BeaconEvent.INVALID_ACCOUNT_DEACTIVATED]: [defaultEventCallbacks.INVALID_ACCOUNT_DEACTIVATED],
[BeaconEvent.SHOW_PREPARE]: [defaultEventCallbacks.SHOW_PREPARE],
[BeaconEvent.HIDE_UI]: [defaultEventCallbacks.HIDE_UI],
[BeaconEvent.PAIR_INIT]: [defaultEventCallbacks.PAIR_INIT],
[BeaconEvent.PAIR_SUCCESS]: [defaultEventCallbacks.PAIR_SUCCESS],
[BeaconEvent.OPEN_BUG_REPORT]: [showBugReportForm],
[BeaconEvent.CHANNEL_CLOSED]: [defaultEventCallbacks.CHANNEL_CLOSED],
[BeaconEvent.INTERNAL_ERROR]: [defaultEventCallbacks.INTERNAL_ERROR],
[BeaconEvent.RELAYER_ERROR]: [defaultEventCallbacks.RELAYER_ERROR],
[BeaconEvent.UNKNOWN]: [defaultEventCallbacks.UNKNOWN]
};
constructor(eventsToOverride = {}, overrideAll) {
if (overrideAll) {
this.setAllHandlers();
}
this.overrideDefaults(eventsToOverride);
}
/**
* A method to subscribe to a specific beacon event and register a callback
*
* @param event The event being emitted
* @param eventCallback The callback that will be invoked
*/
async on(event, eventCallback) {
const listeners = this.callbackMap[event] || [];
listeners.push(eventCallback);
this.callbackMap[event] = listeners;
}
/**
* Emit a beacon event
*
* @param event The event being emitted
* @param data The data to be emit
*/
async emit(event, data, eventCallback) {
const listeners = this.callbackMap[event];
if (listeners && listeners.length > 0) {
listeners.forEach(async (listener) => {
try {
await listener(data, eventCallback);
}
catch (listenerError) {
logger.error(`error handling event ${event}`, listenerError);
}
});
}
}
/**
* Override beacon event default callbacks. This can be used to disable default alert/toast behaviour
*
* @param eventsToOverride An object with the events to override
*/
overrideDefaults(eventsToOverride) {
Object.keys(eventsToOverride).forEach((untypedEvent) => {
const eventType = untypedEvent;
const event = eventsToOverride[eventType];
if (event) {
this.callbackMap[eventType] = [event.handler];
}
});
}
/**
* Set all event callbacks to a specific handler.
*/
setAllHandlers(handler) {
Object.keys(this.callbackMap).forEach((untypedEvent) => {
const eventType = untypedEvent;
this.callbackMap[eventType] = [];
if (handler) {
this.callbackMap[eventType].push(handler);
}
else {
this.callbackMap[eventType].push((...data) => {
logger.log(untypedEvent, ...data);
});
}
});
}
}
//# sourceMappingURL=events.js.map