@dfinity/oisy-wallet-signer
Version:
A library designed to facilitate communication between a dApp and the OISY Wallet on the Internet Computer.
178 lines (177 loc) • 9.02 kB
TypeScript
import type { SignerOptions } from './types/signer-options';
import { type Prompts, type RegisterPrompts } from './types/signer-prompts';
export declare class Signer {
#private;
private constructor();
/**
* Creates a signer that listens and communicates with a relying party.
*
* @static
* @param {SignerOptions} options - The options for the signer.
* @returns {Signer} The connected signer.
*/
static init(options: SignerOptions): Signer;
/**
* Disconnects the signer, removing the message event listener and cleanup.
* @returns {void}
*/
disconnect: () => void;
private readonly onMessageListener;
private readonly onMessage;
/**
* Handles a potential readonly-only message request.
*
* The readonly-only message request might be triggered while the signer is busy processing requests.
* Since these informative requests do not impact the signer's behavior, it is acceptable to provide a response read-only requests.
*
* @private
* @param {SignerMessageEvent} message - The message event to process.
* @returns {{ handled: boolean }} - An object indicating whether the message was handled.
*/
private handleReadOnlyMessage;
private handleMessage;
private setWalletOrigin;
/**
* When establishing a connection, validates the origin of a message event to ensure it matches the existing wallet origin - i.e. subsequent status requests - or is undefined - i.e. first status request.
* If the origin is invalid, it sends an error notification with the appropriate error code and message.
*
* @private
* @param {object} event - The message event to validate.
* @param {any} event.data - The data sent in the message event.
* @param {string} event.origin - The origin of the message event.
*
* @returns {object} An object containing a `valid` boolean property.
* @returns {boolean} returns `true` if the origin is either undefined or matches the expected wallet origin, otherwise returns `false` and notifies the error.
*/
private assertUndefinedOrSameOrigin;
/**
* Checks if the signer is busy and notifies the relying party if it is.
*
* This is required for security reason to avoid the consumer of the signer to for example process a call canister while at the same time new permissions are requested.
*
* @private
* @param {object} event - The message event to validate.
* @param {any} event.data - The data sent in the message event.
* @param {string} event.origin - The origin of the message event.
*
* @returns {object} An object containing a `busy` boolean property.
* @returns {boolean} returns true` if the signer is busy, otherwise `false`.
*/
private assertNotBusy;
private handleWithBusy;
private setIdle;
/**
* Validates that the wallet origin is defined and matches the origin of the message event that established the connection.
* If the origin is invalid or the wallet origin is not defined, it sends an error notification
* with the appropriate error code and message.
*
* @private
* @param {object} event - The message event to validate.
* @param {any} event.data - The data sent in the message event.
* @param {string} event.origin - The origin of the message event.
*
* @returns {object} An object containing a `valid` boolean property.
* @returns {boolean} returns `true` if the wallet origin is defined and matches the origin of the message event, otherwise returns `false` and notifies the error.
*/
private assertNotUndefinedAndSameOrigin;
/**
* Registers a prompt handler for a specified method in the signer service.
*
* @template T
* @param {RegisterPrompts<T>} options - An object containing the method and corresponding prompt handler.
* @param {T} options.method - The method for which the prompt handler is being registered. Supported methods include ICRC standards.
* @param {Prompts[T]} options.prompt - The prompt handler that should be registered. The prompt type depends on the method being registered.
*
* @throws {Error} Throws an error if the method is not supported or the prompt type does not match the expected type for the given method.
*
* @example
* // Register a permissions prompt
* register({
* method: 'icrc25_request_permissions', // or alternatively using related constant ICRC25_REQUEST_PERMISSIONS
* prompt: (payload) => {
* payload.confirm(requestedScopes);
* }
* });
*/
register: <T extends keyof Prompts>({ method, prompt }: RegisterPrompts<T>) => void;
/**
* Handles incoming status requests.
*
* Parses the message data to determine if it conforms to a status request, sends a notification indicating that the signer is ready and set the origin for asserting subsequent calls.
*
* @param {SignerMessageEvent} message - The incoming message event containing the data and origin.
* @returns {Object} An object with a boolean property `handled` indicating whether the request was handled.
*/
private handleStatusRequest;
/**
* Handles incoming messages to list the supported standards.
*
* Parses the message data to determine if it conforms to a supported standards request and responds with a notification with the supported standards.
*
* @param {SignerMessageEvent} message - The incoming message event containing the data and origin.
* @returns {Object} An object with a boolean property `handled` indicating whether the request was handled.
*/
private handleSupportedStandards;
/**
* Handles incoming messages to list the permissions.
*
* Parses the message data to determine if it conforms to a permissions request and responds with a notification with the scopes of the permissions.
*
* @param {SignerMessageEvent} message - The incoming message event containing the data and origin.
* @returns {Object} An object with a boolean property `handled` indicating whether the request was handled.
*/
private handlePermissionsRequest;
/**
* Handles incoming messages to request permissions.
*
* Parses the message data to determine if it conforms to a request permissions schema. If it does,
* forwards the parameters to the clients, as requesting permissions requires the user to review
* and approve or decline them.
*
* @param {SignerMessageEvent} message - The incoming message event containing the data and origin.
* @returns {Object} An object with a boolean property `handled` indicating whether the request was processed as a permissions request.
*/
private handleRequestPermissionsRequest;
private promptPermissions;
private emitPermissions;
private assertWalletOriginAndNotifyMissingPromptError;
private savePermissions;
/**
* Handles incoming messages to list the accounts.
*
* Parses the message data to determine if it conforms to a accounts request and responds with the accounts if the permissions are granted.
*
* @param {SignerMessageEvent} message - The incoming message event containing the data and origin.
* @returns {Object} An object with a boolean property `handled` indicating whether the request was handled.
*/
private handleAccounts;
private prompt;
private promptAccounts;
/**
* Handles incoming messages to call a canister.
*
* Parses the message data to determine if it conforms to a call canister request and responds with the result of the call if the permissions are granted and if the user accept the consent message.
*
* @param {SignerMessageEvent} message - The incoming message event containing the data and origin.
* @returns {Object} An object with a boolean property `handled` indicating whether the request was handled.
*/
private handleCallCanister;
/**
* Asserts the current permission state for the given method and origin. If the permission
* is set to 'ask_on_use', prompts the user for permission and returns the updated state.
*
* @private
* @async
* @function
* @param {Object} params - The parameters for the function.
* @param {IcrcScopedMethod} params.method - The method for which permissions are being checked.
* @param {string} params.origin - The origin from where the request is made.
* @param {RpcId} params.requestId - The unique identifier for the RPC request.
*
* @returns {Promise<Omit<IcrcPermissionState, 'ask_on_use'>>} - A promise that resolves to the updated
* permission state ('granted' or 'denied'), or the current permission if no prompt is needed.
*
* @throws {Error} - Throws an error if the permission prompt fails.
*/
private assertAndPromptPermissions;
}