@metamask/approval-controller
Advanced tools
Comparing version 3.3.0 to 3.4.0
@@ -9,2 +9,6 @@ # Changelog | ||
## [3.4.0] | ||
### Added | ||
- Add `success` and `error` methods to display result pages ([#1442](https://github.com/MetaMask/core/pull/1442)) | ||
## [3.3.0] | ||
@@ -63,3 +67,4 @@ ### Added | ||
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@3.3.0...HEAD | ||
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@3.4.0...HEAD | ||
[3.4.0]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@3.3.0...@metamask/approval-controller@3.4.0 | ||
[3.3.0]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@3.2.0...@metamask/approval-controller@3.3.0 | ||
@@ -66,0 +71,0 @@ [3.2.0]: https://github.com/MetaMask/core/compare/@metamask/approval-controller@3.1.0...@metamask/approval-controller@3.2.0 |
@@ -5,5 +5,16 @@ import type { Patch } from 'immer'; | ||
import { Json, OptionalField } from '@metamask/utils'; | ||
export declare const ORIGIN_METAMASK = "metamask"; | ||
export declare const APPROVAL_TYPE_RESULT_ERROR = "result_error"; | ||
export declare const APPROVAL_TYPE_RESULT_SUCCESS = "result_success"; | ||
declare const controllerName = "ApprovalController"; | ||
declare type ApprovalRequestData = Record<string, Json> | null; | ||
declare type ApprovalRequestState = Record<string, Json> | null; | ||
declare type ApprovalFlow = { | ||
id: string; | ||
loadingText: string | null; | ||
}; | ||
declare type ResultOptions = { | ||
flowToEnd?: string; | ||
header?: (string | ResultComponent)[]; | ||
}; | ||
export declare type ApprovalRequest<RequestData extends ApprovalRequestData> = { | ||
@@ -40,7 +51,2 @@ /** | ||
}; | ||
declare type ShowApprovalRequest = () => void | Promise<void>; | ||
declare type ApprovalFlow = { | ||
id: string; | ||
loadingText: string | null; | ||
}; | ||
export declare type ApprovalFlowState = ApprovalFlow; | ||
@@ -52,11 +58,29 @@ export declare type ApprovalControllerState = { | ||
}; | ||
export declare type GetApprovalsState = { | ||
type: `${typeof controllerName}:getState`; | ||
handler: () => ApprovalControllerState; | ||
export declare type ApprovalControllerMessenger = RestrictedControllerMessenger<typeof controllerName, ApprovalControllerActions, ApprovalControllerEvents, string, string>; | ||
export declare type ShowApprovalRequest = () => void | Promise<void>; | ||
export declare type ResultComponent = { | ||
/** | ||
* A unique identifier for this instance of the component. | ||
*/ | ||
key: string; | ||
/** | ||
* The name of the component to render. | ||
*/ | ||
name: string; | ||
/** | ||
* Any properties required by the component. | ||
*/ | ||
properties?: Record<string, unknown>; | ||
/** | ||
* Any child components to render inside the component. | ||
*/ | ||
children?: string | ResultComponent | (string | ResultComponent)[]; | ||
}; | ||
export declare type ClearApprovalRequests = { | ||
type: `${typeof controllerName}:clearRequests`; | ||
handler: (error: EthereumRpcError<unknown>) => void; | ||
export declare type ApprovalControllerOptions = { | ||
messenger: ApprovalControllerMessenger; | ||
showApprovalRequest: ShowApprovalRequest; | ||
state?: Partial<ApprovalControllerState>; | ||
typesExcludedFromRateLimiting?: string[]; | ||
}; | ||
declare type AddApprovalOptions = { | ||
export declare type AddApprovalOptions = { | ||
id?: string; | ||
@@ -69,26 +93,6 @@ origin: string; | ||
}; | ||
export declare type AddApprovalRequest = { | ||
type: `${typeof controllerName}:addRequest`; | ||
handler: (opts: AddApprovalOptions, shouldShowRequest: boolean) => ReturnType<ApprovalController['add']>; | ||
}; | ||
export declare type HasApprovalRequest = { | ||
type: `${typeof controllerName}:hasRequest`; | ||
handler: ApprovalController['has']; | ||
}; | ||
export declare type AcceptRequest = { | ||
type: `${typeof controllerName}:acceptRequest`; | ||
handler: ApprovalController['accept']; | ||
}; | ||
export declare type RejectRequest = { | ||
type: `${typeof controllerName}:rejectRequest`; | ||
handler: ApprovalController['reject']; | ||
}; | ||
declare type UpdateRequestStateOptions = { | ||
export declare type UpdateRequestStateOptions = { | ||
id: string; | ||
requestState: Record<string, Json>; | ||
}; | ||
export declare type UpdateRequestState = { | ||
type: `${typeof controllerName}:updateRequestState`; | ||
handler: ApprovalController['updateRequestState']; | ||
}; | ||
export declare type AcceptOptions = { | ||
@@ -102,8 +106,11 @@ /** | ||
}; | ||
export declare type AcceptResult = { | ||
/** | ||
* An optional value provided by the request creator when indicating a successful result. | ||
*/ | ||
value?: unknown; | ||
export declare type StartFlowOptions = OptionalField<ApprovalFlow, 'id' | 'loadingText'>; | ||
export declare type EndFlowOptions = Pick<ApprovalFlow, 'id'>; | ||
export declare type SetFlowLoadingTextOptions = ApprovalFlow; | ||
export declare type SuccessOptions = ResultOptions & { | ||
message?: string | ResultComponent | (string | ResultComponent)[]; | ||
}; | ||
export declare type ErrorOptions = ResultOptions & { | ||
error?: string | ResultComponent | (string | ResultComponent)[]; | ||
}; | ||
export declare type AcceptResultCallbacks = { | ||
@@ -134,6 +141,44 @@ /** | ||
}; | ||
export declare type StartFlowOptions = OptionalField<ApprovalFlow, 'id' | 'loadingText'>; | ||
export declare type AcceptResult = { | ||
/** | ||
* An optional value provided by the request creator when indicating a successful result. | ||
*/ | ||
value?: unknown; | ||
}; | ||
export declare type ApprovalFlowStartResult = ApprovalFlow; | ||
export declare type EndFlowOptions = Pick<ApprovalFlow, 'id'>; | ||
export declare type SetFlowLoadingTextOptions = ApprovalFlow; | ||
export declare type SuccessResult = Record<string, never>; | ||
export declare type ErrorResult = Record<string, never>; | ||
export declare type ApprovalStateChange = { | ||
type: `${typeof controllerName}:stateChange`; | ||
payload: [ApprovalControllerState, Patch[]]; | ||
}; | ||
export declare type ApprovalControllerEvents = ApprovalStateChange; | ||
export declare type GetApprovalsState = { | ||
type: `${typeof controllerName}:getState`; | ||
handler: () => ApprovalControllerState; | ||
}; | ||
export declare type ClearApprovalRequests = { | ||
type: `${typeof controllerName}:clearRequests`; | ||
handler: (error: EthereumRpcError<unknown>) => void; | ||
}; | ||
export declare type AddApprovalRequest = { | ||
type: `${typeof controllerName}:addRequest`; | ||
handler: (opts: AddApprovalOptions, shouldShowRequest: boolean) => ReturnType<ApprovalController['add']>; | ||
}; | ||
export declare type HasApprovalRequest = { | ||
type: `${typeof controllerName}:hasRequest`; | ||
handler: ApprovalController['has']; | ||
}; | ||
export declare type AcceptRequest = { | ||
type: `${typeof controllerName}:acceptRequest`; | ||
handler: ApprovalController['accept']; | ||
}; | ||
export declare type RejectRequest = { | ||
type: `${typeof controllerName}:rejectRequest`; | ||
handler: ApprovalController['reject']; | ||
}; | ||
export declare type UpdateRequestState = { | ||
type: `${typeof controllerName}:updateRequestState`; | ||
handler: ApprovalController['updateRequestState']; | ||
}; | ||
export declare type StartFlow = { | ||
@@ -151,15 +196,11 @@ type: `${typeof controllerName}:startFlow`; | ||
}; | ||
export declare type ApprovalControllerActions = GetApprovalsState | ClearApprovalRequests | AddApprovalRequest | HasApprovalRequest | AcceptRequest | RejectRequest | UpdateRequestState | StartFlow | EndFlow | SetFlowLoadingText; | ||
export declare type ApprovalStateChange = { | ||
type: `${typeof controllerName}:stateChange`; | ||
payload: [ApprovalControllerState, Patch[]]; | ||
export declare type ShowSuccess = { | ||
type: `${typeof controllerName}:showSuccess`; | ||
handler: ApprovalController['success']; | ||
}; | ||
export declare type ApprovalControllerEvents = ApprovalStateChange; | ||
export declare type ApprovalControllerMessenger = RestrictedControllerMessenger<typeof controllerName, ApprovalControllerActions, ApprovalControllerEvents, string, string>; | ||
declare type ApprovalControllerOptions = { | ||
messenger: ApprovalControllerMessenger; | ||
showApprovalRequest: ShowApprovalRequest; | ||
state?: Partial<ApprovalControllerState>; | ||
typesExcludedFromRateLimiting?: string[]; | ||
export declare type ShowError = { | ||
type: `${typeof controllerName}:showError`; | ||
handler: ApprovalController['error']; | ||
}; | ||
export declare type ApprovalControllerActions = GetApprovalsState | ClearApprovalRequests | AddApprovalRequest | HasApprovalRequest | AcceptRequest | RejectRequest | UpdateRequestState | StartFlow | EndFlow | SetFlowLoadingText | ShowSuccess | ShowError; | ||
/** | ||
@@ -175,6 +216,3 @@ * Controller for managing requests that require user approval. | ||
export declare class ApprovalController extends BaseControllerV2<typeof controllerName, ApprovalControllerState, ApprovalControllerMessenger> { | ||
private _approvals; | ||
private _origins; | ||
private _showApprovalRequest; | ||
private _typesExcludedFromRateLimiting; | ||
#private; | ||
/** | ||
@@ -384,63 +422,23 @@ * Construct an Approval controller. | ||
/** | ||
* Implementation of add operation. | ||
* Show a success page. | ||
* | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
* @param id - The id of the approval request. | ||
* @param requestData - The request data associated with the approval request. | ||
* @param requestState - The request state associated with the approval request. | ||
* @param expectsResult - Whether the approval request expects a result object to be returned. | ||
* @returns The approval promise. | ||
* @param opts - Options bag. | ||
* @param opts.message - The message text or components to display in the page. | ||
* @param opts.header - The text or components to display in the header of the page. | ||
* @param opts.flowToEnd - The ID of the approval flow to end once the success page is approved. | ||
* @returns Empty object to support future additions. | ||
*/ | ||
private _add; | ||
success(opts?: SuccessOptions): Promise<SuccessResult>; | ||
/** | ||
* Validates parameters to the add method. | ||
* Show an error page. | ||
* | ||
* @param id - The id of the approval request. | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
* @param requestData - The request data associated with the approval request. | ||
* @param requestState - The request state associated with the approval request. | ||
* @param opts - Options bag. | ||
* @param opts.message - The message text or components to display in the page. | ||
* @param opts.header - The text or components to display in the header of the page. | ||
* @param opts.flowToEnd - The ID of the approval flow to end once the error page is approved. | ||
* @returns Empty object to support future additions. | ||
*/ | ||
private _validateAddParams; | ||
/** | ||
* Adds an entry to _origins. | ||
* Performs no validation. | ||
* | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
*/ | ||
private _addPendingApprovalOrigin; | ||
/** | ||
* Adds an entry to the store. | ||
* Performs no validation. | ||
* | ||
* @param id - The id of the approval request. | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
* @param requestData - The request data associated with the approval request. | ||
* @param requestState - The request state associated with the approval request. | ||
* @param expectsResult - Whether the request expects a result object to be returned. | ||
*/ | ||
private _addToStore; | ||
/** | ||
* Deletes the approval with the given id. The approval promise must be | ||
* resolved or reject before this method is called. | ||
* Deletion is an internal operation because approval state is solely | ||
* managed by this controller. | ||
* | ||
* @param id - The id of the approval request to be deleted. | ||
*/ | ||
private _delete; | ||
/** | ||
* Gets the approval callbacks for the given id, deletes the entry, and then | ||
* returns the callbacks for promise resolution. | ||
* Throws an error if no approval is found for the given id. | ||
* | ||
* @param id - The id of the approval request. | ||
* @returns The promise callbacks associated with the approval request. | ||
*/ | ||
private _deleteApprovalAndGetCallbacks; | ||
error(opts?: ErrorOptions): Promise<ErrorResult>; | ||
} | ||
export default ApprovalController; | ||
//# sourceMappingURL=ApprovalController.d.ts.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
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 _ApprovalController_instances, _ApprovalController_approvals, _ApprovalController_origins, _ApprovalController_showApprovalRequest, _ApprovalController_typesExcludedFromRateLimiting, _ApprovalController_add, _ApprovalController_validateAddParams, _ApprovalController_addPendingApprovalOrigin, _ApprovalController_addToStore, _ApprovalController_delete, _ApprovalController_deleteApprovalAndGetCallbacks, _ApprovalController_result; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ApprovalController = void 0; | ||
exports.ApprovalController = exports.APPROVAL_TYPE_RESULT_SUCCESS = exports.APPROVAL_TYPE_RESULT_ERROR = exports.ORIGIN_METAMASK = void 0; | ||
const eth_rpc_errors_1 = require("eth-rpc-errors"); | ||
@@ -8,2 +29,7 @@ const nanoid_1 = require("nanoid"); | ||
const errors_1 = require("./errors"); | ||
// Constants | ||
// Avoiding dependency on controller-utils | ||
exports.ORIGIN_METAMASK = 'metamask'; | ||
exports.APPROVAL_TYPE_RESULT_ERROR = 'result_error'; | ||
exports.APPROVAL_TYPE_RESULT_SUCCESS = 'result_success'; | ||
const controllerName = 'ApprovalController'; | ||
@@ -50,6 +76,11 @@ const stateMetadata = { | ||
}); | ||
this._approvals = new Map(); | ||
this._origins = new Map(); | ||
this._showApprovalRequest = showApprovalRequest; | ||
this._typesExcludedFromRateLimiting = typesExcludedFromRateLimiting; | ||
_ApprovalController_instances.add(this); | ||
_ApprovalController_approvals.set(this, void 0); | ||
_ApprovalController_origins.set(this, void 0); | ||
_ApprovalController_showApprovalRequest.set(this, void 0); | ||
_ApprovalController_typesExcludedFromRateLimiting.set(this, void 0); | ||
__classPrivateFieldSet(this, _ApprovalController_approvals, new Map(), "f"); | ||
__classPrivateFieldSet(this, _ApprovalController_origins, new Map(), "f"); | ||
__classPrivateFieldSet(this, _ApprovalController_showApprovalRequest, showApprovalRequest, "f"); | ||
__classPrivateFieldSet(this, _ApprovalController_typesExcludedFromRateLimiting, typesExcludedFromRateLimiting, "f"); | ||
this.registerMessageHandlers(); | ||
@@ -76,10 +107,12 @@ } | ||
this.messagingSystem.registerActionHandler(`${controllerName}:setFlowLoadingText`, this.setFlowLoadingText.bind(this)); | ||
this.messagingSystem.registerActionHandler(`${controllerName}:showSuccess`, this.success.bind(this)); | ||
this.messagingSystem.registerActionHandler(`${controllerName}:showError`, this.error.bind(this)); | ||
} | ||
addAndShowApprovalRequest(opts) { | ||
const promise = this._add(opts.origin, opts.type, opts.id, opts.requestData, opts.requestState, opts.expectsResult); | ||
this._showApprovalRequest(); | ||
const promise = __classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_add).call(this, opts.origin, opts.type, opts.id, opts.requestData, opts.requestState, opts.expectsResult); | ||
__classPrivateFieldGet(this, _ApprovalController_showApprovalRequest, "f").call(this); | ||
return promise; | ||
} | ||
add(opts) { | ||
return this._add(opts.origin, opts.type, opts.id, opts.requestData, opts.requestState, opts.expectsResult); | ||
return __classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_add).call(this, opts.origin, opts.type, opts.id, opts.requestData, opts.requestState, opts.expectsResult); | ||
} | ||
@@ -117,6 +150,6 @@ /** | ||
if (origin && _type) { | ||
return ((_a = this._origins.get(origin)) === null || _a === void 0 ? void 0 : _a.get(_type)) || 0; | ||
return ((_a = __classPrivateFieldGet(this, _ApprovalController_origins, "f").get(origin)) === null || _a === void 0 ? void 0 : _a.get(_type)) || 0; | ||
} | ||
if (origin) { | ||
return Array.from((this._origins.get(origin) || new Map()).values()).reduce((total, value) => total + value, 0); | ||
return Array.from((__classPrivateFieldGet(this, _ApprovalController_origins, "f").get(origin) || new Map()).values()).reduce((total, value) => total + value, 0); | ||
} | ||
@@ -162,3 +195,3 @@ // Only "type" was specified | ||
} | ||
return this._approvals.has(id); | ||
return __classPrivateFieldGet(this, _ApprovalController_approvals, "f").has(id); | ||
} | ||
@@ -174,5 +207,5 @@ if (_type && typeof _type !== 'string') { | ||
if (_type) { | ||
return Boolean((_a = this._origins.get(origin)) === null || _a === void 0 ? void 0 : _a.get(_type)); | ||
return Boolean((_a = __classPrivateFieldGet(this, _ApprovalController_origins, "f").get(origin)) === null || _a === void 0 ? void 0 : _a.get(_type)); | ||
} | ||
return this._origins.has(origin); | ||
return __classPrivateFieldGet(this, _ApprovalController_origins, "f").has(origin); | ||
} | ||
@@ -203,3 +236,3 @@ if (_type) { | ||
const approval = this.get(id); | ||
const requestPromise = this._deleteApprovalAndGetCallbacks(id); | ||
const requestPromise = __classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_deleteApprovalAndGetCallbacks).call(this, id); | ||
return new Promise((resolve, reject) => { | ||
@@ -232,3 +265,3 @@ const resultCallbacks = { | ||
reject(id, error) { | ||
this._deleteApprovalAndGetCallbacks(id).reject(error); | ||
__classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_deleteApprovalAndGetCallbacks).call(this, id).reject(error); | ||
} | ||
@@ -242,6 +275,6 @@ /** | ||
clear(rejectionError) { | ||
for (const id of this._approvals.keys()) { | ||
for (const id of __classPrivateFieldGet(this, _ApprovalController_approvals, "f").keys()) { | ||
this.reject(id, rejectionError); | ||
} | ||
this._origins.clear(); | ||
__classPrivateFieldGet(this, _ApprovalController_origins, "f").clear(); | ||
this.update((draftState) => { | ||
@@ -284,3 +317,3 @@ draftState.pendingApprovals = {}; | ||
}); | ||
this._showApprovalRequest(); | ||
__classPrivateFieldGet(this, _ApprovalController_showApprovalRequest, "f").call(this); | ||
return { id, loadingText }; | ||
@@ -323,150 +356,150 @@ } | ||
/** | ||
* Implementation of add operation. | ||
* Show a success page. | ||
* | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
* @param id - The id of the approval request. | ||
* @param requestData - The request data associated with the approval request. | ||
* @param requestState - The request state associated with the approval request. | ||
* @param expectsResult - Whether the approval request expects a result object to be returned. | ||
* @returns The approval promise. | ||
* @param opts - Options bag. | ||
* @param opts.message - The message text or components to display in the page. | ||
* @param opts.header - The text or components to display in the header of the page. | ||
* @param opts.flowToEnd - The ID of the approval flow to end once the success page is approved. | ||
* @returns Empty object to support future additions. | ||
*/ | ||
_add(origin, type, id = (0, nanoid_1.nanoid)(), requestData, requestState, expectsResult) { | ||
this._validateAddParams(id, origin, type, requestData, requestState); | ||
if (!this._typesExcludedFromRateLimiting.includes(type) && | ||
this.has({ origin, type })) { | ||
throw eth_rpc_errors_1.ethErrors.rpc.resourceUnavailable(getAlreadyPendingMessage(origin, type)); | ||
} | ||
// add pending approval | ||
return new Promise((resolve, reject) => { | ||
this._approvals.set(id, { resolve, reject }); | ||
this._addPendingApprovalOrigin(origin, type); | ||
this._addToStore(id, origin, type, requestData, requestState, expectsResult); | ||
success(opts = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield __classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_result).call(this, exports.APPROVAL_TYPE_RESULT_SUCCESS, opts, { | ||
message: opts.message, | ||
header: opts.header, | ||
}); | ||
return {}; | ||
}); | ||
} | ||
/** | ||
* Validates parameters to the add method. | ||
* Show an error page. | ||
* | ||
* @param id - The id of the approval request. | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
* @param requestData - The request data associated with the approval request. | ||
* @param requestState - The request state associated with the approval request. | ||
* @param opts - Options bag. | ||
* @param opts.message - The message text or components to display in the page. | ||
* @param opts.header - The text or components to display in the header of the page. | ||
* @param opts.flowToEnd - The ID of the approval flow to end once the error page is approved. | ||
* @returns Empty object to support future additions. | ||
*/ | ||
_validateAddParams(id, origin, type, requestData, requestState) { | ||
let errorMessage = null; | ||
if (!id || typeof id !== 'string') { | ||
errorMessage = 'Must specify non-empty string id.'; | ||
} | ||
else if (this._approvals.has(id)) { | ||
errorMessage = `Approval request with id '${id}' already exists.`; | ||
} | ||
else if (!origin || typeof origin !== 'string') { | ||
errorMessage = 'Must specify non-empty string origin.'; | ||
} | ||
else if (!type || typeof type !== 'string') { | ||
errorMessage = 'Must specify non-empty string type.'; | ||
} | ||
else if (requestData && | ||
(typeof requestData !== 'object' || Array.isArray(requestData))) { | ||
errorMessage = 'Request data must be a plain object if specified.'; | ||
} | ||
else if (requestState && | ||
(typeof requestState !== 'object' || Array.isArray(requestState))) { | ||
errorMessage = 'Request state must be a plain object if specified.'; | ||
} | ||
if (errorMessage) { | ||
throw eth_rpc_errors_1.ethErrors.rpc.internal(errorMessage); | ||
} | ||
error(opts = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield __classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_result).call(this, exports.APPROVAL_TYPE_RESULT_ERROR, opts, { | ||
error: opts.error, | ||
header: opts.header, | ||
}); | ||
return {}; | ||
}); | ||
} | ||
/** | ||
* Adds an entry to _origins. | ||
* Performs no validation. | ||
* | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
*/ | ||
_addPendingApprovalOrigin(origin, type) { | ||
let originMap = this._origins.get(origin); | ||
if (!originMap) { | ||
originMap = new Map(); | ||
this._origins.set(origin, originMap); | ||
} | ||
const currentValue = originMap.get(type) || 0; | ||
originMap.set(type, currentValue + 1); | ||
} | ||
exports.ApprovalController = ApprovalController; | ||
_ApprovalController_approvals = new WeakMap(), _ApprovalController_origins = new WeakMap(), _ApprovalController_showApprovalRequest = new WeakMap(), _ApprovalController_typesExcludedFromRateLimiting = new WeakMap(), _ApprovalController_instances = new WeakSet(), _ApprovalController_add = function _ApprovalController_add(origin, type, id = (0, nanoid_1.nanoid)(), requestData, requestState, expectsResult) { | ||
__classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_validateAddParams).call(this, id, origin, type, requestData, requestState); | ||
if (!__classPrivateFieldGet(this, _ApprovalController_typesExcludedFromRateLimiting, "f").includes(type) && | ||
this.has({ origin, type })) { | ||
throw eth_rpc_errors_1.ethErrors.rpc.resourceUnavailable(getAlreadyPendingMessage(origin, type)); | ||
} | ||
/** | ||
* Adds an entry to the store. | ||
* Performs no validation. | ||
* | ||
* @param id - The id of the approval request. | ||
* @param origin - The origin of the approval request. | ||
* @param type - The type associated with the approval request. | ||
* @param requestData - The request data associated with the approval request. | ||
* @param requestState - The request state associated with the approval request. | ||
* @param expectsResult - Whether the request expects a result object to be returned. | ||
*/ | ||
_addToStore(id, origin, type, requestData, requestState, expectsResult) { | ||
const approval = { | ||
id, | ||
origin, | ||
type, | ||
time: Date.now(), | ||
requestData: requestData || null, | ||
requestState: requestState || null, | ||
expectsResult: expectsResult || false, | ||
}; | ||
this.update((draftState) => { | ||
// Typecast: ts(2589) | ||
draftState.pendingApprovals[id] = approval; | ||
draftState.pendingApprovalCount = Object.keys(draftState.pendingApprovals).length; | ||
}); | ||
// add pending approval | ||
return new Promise((resolve, reject) => { | ||
__classPrivateFieldGet(this, _ApprovalController_approvals, "f").set(id, { resolve, reject }); | ||
__classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_addPendingApprovalOrigin).call(this, origin, type); | ||
__classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_addToStore).call(this, id, origin, type, requestData, requestState, expectsResult); | ||
}); | ||
}, _ApprovalController_validateAddParams = function _ApprovalController_validateAddParams(id, origin, type, requestData, requestState) { | ||
let errorMessage = null; | ||
if (!id || typeof id !== 'string') { | ||
errorMessage = 'Must specify non-empty string id.'; | ||
} | ||
/** | ||
* Deletes the approval with the given id. The approval promise must be | ||
* resolved or reject before this method is called. | ||
* Deletion is an internal operation because approval state is solely | ||
* managed by this controller. | ||
* | ||
* @param id - The id of the approval request to be deleted. | ||
*/ | ||
_delete(id) { | ||
this._approvals.delete(id); | ||
// This method is only called after verifying that the approval with the | ||
// specified id exists. | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const { origin, type } = this.state.pendingApprovals[id]; | ||
const originMap = this._origins.get(origin); | ||
const originTotalCount = this.getApprovalCount({ origin }); | ||
const originTypeCount = originMap.get(type); | ||
if (originTotalCount === 1) { | ||
this._origins.delete(origin); | ||
else if (__classPrivateFieldGet(this, _ApprovalController_approvals, "f").has(id)) { | ||
errorMessage = `Approval request with id '${id}' already exists.`; | ||
} | ||
else if (!origin || typeof origin !== 'string') { | ||
errorMessage = 'Must specify non-empty string origin.'; | ||
} | ||
else if (!type || typeof type !== 'string') { | ||
errorMessage = 'Must specify non-empty string type.'; | ||
} | ||
else if (requestData && | ||
(typeof requestData !== 'object' || Array.isArray(requestData))) { | ||
errorMessage = 'Request data must be a plain object if specified.'; | ||
} | ||
else if (requestState && | ||
(typeof requestState !== 'object' || Array.isArray(requestState))) { | ||
errorMessage = 'Request state must be a plain object if specified.'; | ||
} | ||
if (errorMessage) { | ||
throw eth_rpc_errors_1.ethErrors.rpc.internal(errorMessage); | ||
} | ||
}, _ApprovalController_addPendingApprovalOrigin = function _ApprovalController_addPendingApprovalOrigin(origin, type) { | ||
let originMap = __classPrivateFieldGet(this, _ApprovalController_origins, "f").get(origin); | ||
if (!originMap) { | ||
originMap = new Map(); | ||
__classPrivateFieldGet(this, _ApprovalController_origins, "f").set(origin, originMap); | ||
} | ||
const currentValue = originMap.get(type) || 0; | ||
originMap.set(type, currentValue + 1); | ||
}, _ApprovalController_addToStore = function _ApprovalController_addToStore(id, origin, type, requestData, requestState, expectsResult) { | ||
const approval = { | ||
id, | ||
origin, | ||
type, | ||
time: Date.now(), | ||
requestData: requestData || null, | ||
requestState: requestState || null, | ||
expectsResult: expectsResult || false, | ||
}; | ||
this.update((draftState) => { | ||
// Typecast: ts(2589) | ||
draftState.pendingApprovals[id] = approval; | ||
draftState.pendingApprovalCount = Object.keys(draftState.pendingApprovals).length; | ||
}); | ||
}, _ApprovalController_delete = function _ApprovalController_delete(id) { | ||
__classPrivateFieldGet(this, _ApprovalController_approvals, "f").delete(id); | ||
// This method is only called after verifying that the approval with the | ||
// specified id exists. | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const { origin, type } = this.state.pendingApprovals[id]; | ||
const originMap = __classPrivateFieldGet(this, _ApprovalController_origins, "f").get(origin); | ||
const originTotalCount = this.getApprovalCount({ origin }); | ||
const originTypeCount = originMap.get(type); | ||
if (originTotalCount === 1) { | ||
__classPrivateFieldGet(this, _ApprovalController_origins, "f").delete(origin); | ||
} | ||
else { | ||
originMap.set(type, originTypeCount - 1); | ||
} | ||
this.update((draftState) => { | ||
delete draftState.pendingApprovals[id]; | ||
draftState.pendingApprovalCount = Object.keys(draftState.pendingApprovals).length; | ||
}); | ||
}, _ApprovalController_deleteApprovalAndGetCallbacks = function _ApprovalController_deleteApprovalAndGetCallbacks(id) { | ||
const callbacks = __classPrivateFieldGet(this, _ApprovalController_approvals, "f").get(id); | ||
if (!callbacks) { | ||
throw new errors_1.ApprovalRequestNotFoundError(id); | ||
} | ||
__classPrivateFieldGet(this, _ApprovalController_instances, "m", _ApprovalController_delete).call(this, id); | ||
return callbacks; | ||
}, _ApprovalController_result = function _ApprovalController_result(type, opts, requestData) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
yield this.addAndShowApprovalRequest({ | ||
origin: exports.ORIGIN_METAMASK, | ||
type, | ||
requestData, | ||
}); | ||
} | ||
else { | ||
originMap.set(type, originTypeCount - 1); | ||
catch (error) { | ||
console.info('Failed to display result page', error); | ||
} | ||
this.update((draftState) => { | ||
delete draftState.pendingApprovals[id]; | ||
draftState.pendingApprovalCount = Object.keys(draftState.pendingApprovals).length; | ||
}); | ||
} | ||
/** | ||
* Gets the approval callbacks for the given id, deletes the entry, and then | ||
* returns the callbacks for promise resolution. | ||
* Throws an error if no approval is found for the given id. | ||
* | ||
* @param id - The id of the approval request. | ||
* @returns The promise callbacks associated with the approval request. | ||
*/ | ||
_deleteApprovalAndGetCallbacks(id) { | ||
const callbacks = this._approvals.get(id); | ||
if (!callbacks) { | ||
throw new errors_1.ApprovalRequestNotFoundError(id); | ||
finally { | ||
if (opts.flowToEnd) { | ||
try { | ||
this.endFlow({ id: opts.flowToEnd }); | ||
} | ||
catch (error) { | ||
console.info('Failed to end flow', { id: opts.flowToEnd, error }); | ||
} | ||
} | ||
} | ||
this._delete(id); | ||
return callbacks; | ||
} | ||
} | ||
exports.ApprovalController = ApprovalController; | ||
}); | ||
}; | ||
exports.default = ApprovalController; | ||
//# sourceMappingURL=ApprovalController.js.map |
{ | ||
"name": "@metamask/approval-controller", | ||
"version": "3.3.0", | ||
"version": "3.4.0", | ||
"description": "Manages requests that require user approval", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
107288
997