Skip to content

Commit

Permalink
Handle watch asset accept and reject using ApprovalController only (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
bergarces authored Jun 5, 2023
1 parent b5ef94b commit 5355000
Show file tree
Hide file tree
Showing 17 changed files with 631 additions and 157 deletions.
122 changes: 58 additions & 64 deletions .storybook/initial-states/approval-screens/add-suggested-token.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,77 @@
export const suggestedAssets = [
import { ApprovalType } from '@metamask/controller-utils';

const suggestedAssets = [
{
asset: {
address: '0x6b175474e89094c44da98b954eedeac495271d0f',
symbol: 'ETH',
decimals: 18,
image: './images/eth_logo.png',
unlisted: false,
},
address: '0x6b175474e89094c44da98b954eedeac495271d0f',
symbol: 'ETH',
decimals: 18,
image: './images/eth_logo.png',
unlisted: false,
},
{
asset: {
address: '0xB8c77482e45F1F44dE1745F52C74426C631bDD52',
symbol: '0X',
decimals: 18,
image: '0x.svg',
unlisted: false,
},
address: '0xB8c77482e45F1F44dE1745F52C74426C631bDD52',
symbol: '0X',
decimals: 18,
image: '0x.svg',
unlisted: false,
},
{
asset: {
address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
symbol: 'AST',
decimals: 18,
image: 'ast.png',
unlisted: false,
},
address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
symbol: 'AST',
decimals: 18,
image: 'ast.png',
unlisted: false,
},
{
asset: {
address: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
symbol: 'BAT',
decimals: 18,
image: 'BAT_icon.svg',
unlisted: false,
},
address: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
symbol: 'BAT',
decimals: 18,
image: 'BAT_icon.svg',
unlisted: false,
},
{
asset: {
address: '0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1',
symbol: 'CVL',
decimals: 18,
image: 'CVL_token.svg',
unlisted: false,
},
address: '0xe83cccfabd4ed148903bf36d4283ee7c8b3494d1',
symbol: 'CVL',
decimals: 18,
image: 'CVL_token.svg',
unlisted: false,
},
{
asset: {
address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
symbol: 'GLA',
decimals: 18,
image: 'gladius.svg',
unlisted: false,
},
address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
symbol: 'GLA',
decimals: 18,
image: 'gladius.svg',
unlisted: false,
},
{
asset: {
address: '0x467Bccd9d29f223BcE8043b84E8C8B282827790F',
symbol: 'GNO',
decimals: 18,
image: 'gnosis.svg',
unlisted: false,
},
address: '0x467Bccd9d29f223BcE8043b84E8C8B282827790F',
symbol: 'GNO',
decimals: 18,
image: 'gnosis.svg',
unlisted: false,
},
{
asset: {
address: '0xff20817765cb7f73d4bde2e66e067e58d11095c2',
symbol: 'OMG',
decimals: 18,
image: 'omg.jpg',
unlisted: false,
},
address: '0xff20817765cb7f73d4bde2e66e067e58d11095c2',
symbol: 'OMG',
decimals: 18,
image: 'omg.jpg',
unlisted: false,
},
{
asset: {
address: '0x8e870d67f660d95d5be530380d0ec0bd388289e1',
symbol: 'WED',
decimals: 18,
image: 'wed.png',
unlisted: false,
},
address: '0x8e870d67f660d95d5be530380d0ec0bd388289e1',
symbol: 'WED',
decimals: 18,
image: 'wed.png',
unlisted: false,
},
];

export const pendingAssetApprovals = suggestedAssets.map((asset, index) => {
return {
type: ApprovalType.WatchAsset,
requestData: {
id: index,
asset,
},
};
});
1 change: 0 additions & 1 deletion .storybook/test-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,6 @@ const state = {
'0xaD6D458402F60fD3Bd25163575031ACDce07538D': './sai.svg',
},
hiddenTokens: [],
suggestedAssets: [],
useNonceField: false,
usePhishDetect: true,
useTokenDetection: true,
Expand Down
211 changes: 211 additions & 0 deletions .yarn/patches/@metamask-assets-controllers-npm-7.0.0-9dec51787d.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
diff --git a/dist/TokensController.js b/dist/TokensController.js
index 0e03b88e8a46dce73a5cc87fb432b0b2431b3797..fc8893fa6bad76d65aa34fa1bfb0b233b1259ae6 100644
--- a/dist/TokensController.js
+++ b/dist/TokensController.js
@@ -25,13 +25,6 @@ const base_controller_1 = require("@metamask/base-controller");
const controller_utils_1 = require("@metamask/controller-utils");
const assetsUtil_1 = require("./assetsUtil");
const token_service_1 = require("./token-service");
-var SuggestedAssetStatus;
-(function (SuggestedAssetStatus) {
- SuggestedAssetStatus["accepted"] = "accepted";
- SuggestedAssetStatus["failed"] = "failed";
- SuggestedAssetStatus["pending"] = "pending";
- SuggestedAssetStatus["rejected"] = "rejected";
-})(SuggestedAssetStatus || (SuggestedAssetStatus = {}));
/**
* The name of the {@link TokensController}.
*/
@@ -93,10 +86,6 @@ class TokensController extends base_controller_1.BaseController {
});
});
}
- failSuggestedAsset(suggestedAssetMeta, error) {
- const failedSuggestedAssetMeta = Object.assign(Object.assign({}, suggestedAssetMeta), { status: SuggestedAssetStatus.failed, error });
- this.hub.emit(`${suggestedAssetMeta.id}:finished`, failedSuggestedAssetMeta);
- }
/**
* Fetch metadata for a token.
*
@@ -412,9 +401,10 @@ class TokensController extends base_controller_1.BaseController {
_generateRandomId() {
return (0, uuid_1.v1)();
}
+ // THIS PATCHED METHOD HAS ALREADY BEEN RELEASED IN VERSION 8.0.0 of @metamask/assets-controllers
/**
- * Adds a new suggestedAsset to state. Parameters will be validated according to
- * asset type being watched. A `<suggestedAssetMeta.id>:pending` hub event will be emitted once added.
+ * Adds a new suggestedAsset to the list of watched assets.
+ * Parameters will be validated according to the asset type being watched.
*
* @param asset - The asset to be watched. For now only ERC20 tokens are accepted.
* @param type - The asset type.
@@ -423,103 +413,22 @@ class TokensController extends base_controller_1.BaseController {
*/
watchAsset(asset, type, interactingAddress) {
return __awaiter(this, void 0, void 0, function* () {
+ if (type !== controller_utils_1.ERC20) {
+ throw new Error(`Asset of type ${type} not supported`);
+ }
const { selectedAddress } = this.config;
const suggestedAssetMeta = {
asset,
id: this._generateRandomId(),
- status: SuggestedAssetStatus.pending,
time: Date.now(),
type,
interactingAddress: interactingAddress || selectedAddress,
};
- try {
- switch (type) {
- case 'ERC20':
- (0, assetsUtil_1.validateTokenToWatch)(asset);
- break;
- default:
- throw new Error(`Asset of type ${type} not supported`);
- }
- }
- catch (error) {
- this.failSuggestedAsset(suggestedAssetMeta, error);
- return Promise.reject(error);
- }
- const result = new Promise((resolve, reject) => {
- this.hub.once(`${suggestedAssetMeta.id}:finished`, (meta) => {
- switch (meta.status) {
- case SuggestedAssetStatus.accepted:
- return resolve(meta.asset.address);
- case SuggestedAssetStatus.rejected:
- return reject(new Error('User rejected to watch the asset.'));
- case SuggestedAssetStatus.failed:
- return reject(new Error(meta.error.message));
- /* istanbul ignore next */
- default:
- return reject(new Error(`Unknown status: ${meta.status}`));
- }
- });
- });
- const { suggestedAssets } = this.state;
- suggestedAssets.push(suggestedAssetMeta);
- this.update({ suggestedAssets: [...suggestedAssets] });
- this._requestApproval(suggestedAssetMeta);
- return { result, suggestedAssetMeta };
- });
- }
- /**
- * Accepts to watch an asset and updates it's status and deletes the suggestedAsset from state,
- * adding the asset to corresponding asset state. In this case ERC20 tokens.
- * A `<suggestedAssetMeta.id>:finished` hub event is fired after accepted or failure.
- *
- * @param suggestedAssetID - The ID of the suggestedAsset to accept.
- */
- acceptWatchAsset(suggestedAssetID) {
- return __awaiter(this, void 0, void 0, function* () {
- const { selectedAddress } = this.config;
- const { suggestedAssets } = this.state;
- const index = suggestedAssets.findIndex(({ id }) => suggestedAssetID === id);
- const suggestedAssetMeta = suggestedAssets[index];
- try {
- switch (suggestedAssetMeta.type) {
- case 'ERC20':
- const { address, symbol, decimals, image } = suggestedAssetMeta.asset;
- yield this.addToken(address, symbol, decimals, image, (suggestedAssetMeta === null || suggestedAssetMeta === void 0 ? void 0 : suggestedAssetMeta.interactingAddress) || selectedAddress);
- this._acceptApproval(suggestedAssetID);
- const acceptedSuggestedAssetMeta = Object.assign(Object.assign({}, suggestedAssetMeta), { status: SuggestedAssetStatus.accepted });
- this.hub.emit(`${suggestedAssetMeta.id}:finished`, acceptedSuggestedAssetMeta);
- break;
- default:
- throw new Error(`Asset of type ${suggestedAssetMeta.type} not supported`);
- }
- }
- catch (error) {
- this.failSuggestedAsset(suggestedAssetMeta, error);
- this._rejectApproval(suggestedAssetID);
- }
- const newSuggestedAssets = suggestedAssets.filter(({ id }) => id !== suggestedAssetID);
- this.update({ suggestedAssets: [...newSuggestedAssets] });
+ (0, assetsUtil_1.validateTokenToWatch)(asset);
+ yield this._requestApproval(suggestedAssetMeta);
+ yield this.addToken(asset.address, asset.symbol, asset.decimals, asset.image, suggestedAssetMeta.interactingAddress);
});
}
- /**
- * Rejects a watchAsset request based on its ID by setting its status to "rejected"
- * and emitting a `<suggestedAssetMeta.id>:finished` hub event.
- *
- * @param suggestedAssetID - The ID of the suggestedAsset to accept.
- */
- rejectWatchAsset(suggestedAssetID) {
- const { suggestedAssets } = this.state;
- const index = suggestedAssets.findIndex(({ id }) => suggestedAssetID === id);
- const suggestedAssetMeta = suggestedAssets[index];
- if (!suggestedAssetMeta) {
- return;
- }
- const rejectedSuggestedAssetMeta = Object.assign(Object.assign({}, suggestedAssetMeta), { status: SuggestedAssetStatus.rejected });
- this.hub.emit(`${suggestedAssetMeta.id}:finished`, rejectedSuggestedAssetMeta);
- const newSuggestedAssets = suggestedAssets.filter(({ id }) => id !== suggestedAssetID);
- this.update({ suggestedAssets: [...newSuggestedAssets] });
- this._rejectApproval(suggestedAssetID);
- }
/**
* Takes a new tokens and ignoredTokens array for the current network/account combination
* and returns new allTokens and allIgnoredTokens state to update to.
@@ -576,43 +485,26 @@ class TokensController extends base_controller_1.BaseController {
clearIgnoredTokens() {
this.update({ ignoredTokens: [], allIgnoredTokens: {} });
}
+ // THIS PATCHED METHOD HAS ALREADY BEEN RELEASED IN VERSION 8.0.0 of @metamask/assets-controllers
_requestApproval(suggestedAssetMeta) {
- this.messagingSystem
- .call('ApprovalController:addRequest', {
- id: suggestedAssetMeta.id,
- origin: controller_utils_1.ORIGIN_METAMASK,
- type: controller_utils_1.ApprovalType.WatchAsset,
- requestData: {
+ return __awaiter(this, void 0, void 0, function* () {
+ return this.messagingSystem.call('ApprovalController:addRequest', {
id: suggestedAssetMeta.id,
- interactingAddress: suggestedAssetMeta.interactingAddress,
- asset: {
- address: suggestedAssetMeta.asset.address,
- decimals: suggestedAssetMeta.asset.decimals,
- symbol: suggestedAssetMeta.asset.symbol,
- image: suggestedAssetMeta.asset.image || null,
+ origin: controller_utils_1.ORIGIN_METAMASK,
+ type: controller_utils_1.ApprovalType.WatchAsset,
+ requestData: {
+ id: suggestedAssetMeta.id,
+ interactingAddress: suggestedAssetMeta.interactingAddress,
+ asset: {
+ address: suggestedAssetMeta.asset.address,
+ decimals: suggestedAssetMeta.asset.decimals,
+ symbol: suggestedAssetMeta.asset.symbol,
+ image: suggestedAssetMeta.asset.image || null,
+ },
},
- },
- }, true)
- .catch(() => {
- // Intentionally ignored as promise not currently used
+ }, true);
});
}
- _acceptApproval(approvalRequestId) {
- try {
- this.messagingSystem.call('ApprovalController:acceptRequest', approvalRequestId);
- }
- catch (error) {
- console.error('Failed to accept token watch approval request', error);
- }
- }
- _rejectApproval(approvalRequestId) {
- try {
- this.messagingSystem.call('ApprovalController:rejectRequest', approvalRequestId, new Error('Rejected'));
- }
- catch (messageCallError) {
- console.error('Failed to reject token watch approval request', messageCallError);
- }
- }
}
exports.TokensController = TokensController;
exports.default = TokensController;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ethErrors } from 'eth-rpc-errors';
import { MESSAGE_TYPE } from '../../../../../shared/constants/app';

const watchAsset = {
Expand Down Expand Up @@ -37,14 +36,10 @@ async function watchAssetHandler(
) {
try {
const { options: asset, type } = req.params;
const handleWatchAssetResult = await handleWatchAssetRequest(asset, type);
await handleWatchAssetResult.result;
await handleWatchAssetRequest(asset, type);
res.result = true;
return end();
} catch (error) {
if (error.message === 'User rejected to watch the asset.') {
return end(ethErrors.provider.userRejectedRequest());
}
return end(error);
}
}
4 changes: 0 additions & 4 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2121,10 +2121,6 @@ export default class MetamaskController extends EventEmitter {
preferencesController,
),
addToken: tokensController.addToken.bind(tokensController),
rejectWatchAsset:
tokensController.rejectWatchAsset.bind(tokensController),
acceptWatchAsset:
tokensController.acceptWatchAsset.bind(tokensController),
updateTokenType: tokensController.updateTokenType.bind(tokensController),
setAccountLabel: preferencesController.setAccountLabel.bind(
preferencesController,
Expand Down
Loading

0 comments on commit 5355000

Please sign in to comment.