From 0fa9a874e89a2b7b8fb305d420db7f5edc63e425 Mon Sep 17 00:00:00 2001 From: rocky-fleek Date: Sat, 3 Dec 2022 18:30:30 -0600 Subject: [PATCH 1/2] Removed callbacks from reviewPendingTransaction. Added missing awaits. Refactored transactionId hooks to make them promises and handle them with async await. Added clear transactions on controller instantiation. Made transactionIds persistent in storage --- source/Modules/Controller/controllerBase.js | 18 ++++---- source/Modules/Controller/transaction.js | 1 + source/Modules/storageManager.js | 41 ++++++++++++++----- .../Popup/components/AllowAgent/index.jsx | 2 +- .../Popup/components/AppConnection/index.jsx | 2 +- .../components/BurnXTC/hooks/useRequests.jsx | 4 +- .../Popup/components/ImportToken/index.jsx | 2 +- .../Popup/components/LoginProxy/index.jsx | 2 +- .../Popup/components/Principal/index.jsx | 2 +- .../hooks/useRPCTransactions.jsx | 2 +- .../components/Sign/hooks/useRequest.jsx | 2 +- .../components/Sign/hooks/useRequests.jsx | 4 +- .../Popup/components/SignMessage/index.jsx | 2 +- .../components/Transfer/hooks/useRequests.jsx | 6 +-- 14 files changed, 58 insertions(+), 32 deletions(-) diff --git a/source/Modules/Controller/controllerBase.js b/source/Modules/Controller/controllerBase.js index 5c234de7..cf28334e 100644 --- a/source/Modules/Controller/controllerBase.js +++ b/source/Modules/Controller/controllerBase.js @@ -1,7 +1,12 @@ import qs from 'query-string'; import extension from 'extensionizer'; -import { checkPendingTransaction, createPendingTransaction, removePendingTransaction } from '@modules/storageManager'; +import { + checkPendingTransaction, + createPendingTransaction, + removePendingTransaction, + resetPendingTransactions, +} from '@modules/storageManager'; import ERRORS from '@background/errors'; import SIZES from '../../views/Popup/components/Transfer/constants'; @@ -30,6 +35,7 @@ export class ControllerModuleBase { this.keyring = keyring; this.secureController = secureController; this.backgroundController = backgroundController; + resetPendingTransactions(); } secureWrapper({ args, handlerObject }) { @@ -48,9 +54,8 @@ export class ControllerModuleBase { return this.secureController( args[0].callback, async () => { - createPendingTransaction((transactionId) => { - handlerObject.handler(...newArgs, transactionId); - }); + const transactionId = await createPendingTransaction(); + await handlerObject.handler(...newArgs, transactionId); }, ); } @@ -66,9 +71,8 @@ export class ControllerModuleBase { return this.secureController( methodArgs[0].callback, async () => { - handlerObject.handler(...methodArgs); - removePendingTransaction(transactionId, () => { - }); + await handlerObject.handler(...methodArgs); + await removePendingTransaction(transactionId); }, ); }); diff --git a/source/Modules/Controller/transaction.js b/source/Modules/Controller/transaction.js index 9ead5049..e9d34cbb 100644 --- a/source/Modules/Controller/transaction.js +++ b/source/Modules/Controller/transaction.js @@ -441,6 +441,7 @@ export class TransactionModule extends ControllerModuleBase { return { methodName: 'requestCall', handler: async (opts, metadata, args, batchTxId, decodedArgs, transactionId) => { + console.log('calling requestCall', transactionId); const { message, sender, callback } = opts; const { id: callId } = message.data.data; const { id: portId } = sender; diff --git a/source/Modules/storageManager.js b/source/Modules/storageManager.js index 7039b697..6451020d 100644 --- a/source/Modules/storageManager.js +++ b/source/Modules/storageManager.js @@ -183,10 +183,29 @@ export const setDabContacts = (dabContacts = [], cb = () => ([])) => { secureSetWrapper({ dabContacts }, [], cb); }; -export const createPendingTransaction = (cb) => { +const setActiveTransactions = (newActiveTransactions) => new Promise((resolve) => { + secureSetWrapper({ activeTransactions: newActiveTransactions }, {}, resolve); +}); + +const getActiveTransactions = () => new Promise((resolve) => { + const defaultValue = {}; + secureGetWrapper('activeTransactions', defaultValue, (state) => { + const activeTransactions = state?.activeTransactions || defaultValue; + resolve(activeTransactions); + }); +}); + +export const createPendingTransaction = async () => { const id = uuidv4(); - secureSetWrapper({ activeTransactions: { [id]: 'pending' } }, {}, () => cb(id)); + const activeTransactions = await getActiveTransactions(); + const newActiveTransactions = { + ...activeTransactions, + [id]: 'pending', + }; + await setActiveTransactions(newActiveTransactions); + return id; }; + export const checkPendingTransaction = (transactionId, cb) => { secureGetWrapper('activeTransactions', 'pending', (entry) => { cb(entry.activeTransactions[transactionId]); @@ -194,19 +213,21 @@ export const checkPendingTransaction = (transactionId, cb) => { }; export const reviewPendingTransaction = async (transactionId) => { + const activeTransactions = await getActiveTransactions(); const getTxStatus = () => new Promise((resolve) => { checkPendingTransaction(transactionId, resolve); }); - const setData = () => new Promise((resolve) => { - secureSetWrapper({ activeTransactions: { [transactionId]: 'reviewed' } }, {}, resolve); - }); + const newActiveTransactions = { ...activeTransactions, [transactionId]: 'reviewed' }; const txStatus = await getTxStatus(); - if (txStatus !== 'pending') throw new Error('Unauthorized review'); - const result = await setData(); - return result; + if (txStatus === 'pending') { + return setActiveTransactions(newActiveTransactions); + } + return null; }; -export const removePendingTransaction = (transactionId, cb) => { - secureSetWrapper({ activeTransactions: { [transactionId]: undefined } }, {}, cb); +export const removePendingTransaction = async (transactionId) => { + const activeTransactions = await getActiveTransactions(); + const newActiveTransactions = { ...activeTransactions, [transactionId]: undefined }; + await setActiveTransactions(newActiveTransactions); }; export const resetPendingTransactions = () => { diff --git a/source/views/Popup/components/AllowAgent/index.jsx b/source/views/Popup/components/AllowAgent/index.jsx index d8b9d0be..f391248f 100644 --- a/source/views/Popup/components/AllowAgent/index.jsx +++ b/source/views/Popup/components/AllowAgent/index.jsx @@ -58,7 +58,7 @@ const AllowAgent = ({ const [expand, setExpand] = useState(false); const handleAllowAgent = async (status) => { - reviewPendingTransaction(transactionId, () => {}); + await reviewPendingTransaction(transactionId); const success = await portRPC.call('handleAllowAgent', [ url, { status, whitelist: args.whitelist || {}, metadata }, diff --git a/source/views/Popup/components/AppConnection/index.jsx b/source/views/Popup/components/AppConnection/index.jsx index 0842dfff..02d6e67f 100644 --- a/source/views/Popup/components/AppConnection/index.jsx +++ b/source/views/Popup/components/AppConnection/index.jsx @@ -58,7 +58,7 @@ const AppConnection = ({ setOnTimeout, transactionId, metadata }) => { } = query; const handleResponse = async () => { - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); const success = await portRPC.call( 'handleAllowAgent', [ diff --git a/source/views/Popup/components/BurnXTC/hooks/useRequests.jsx b/source/views/Popup/components/BurnXTC/hooks/useRequests.jsx index 0e011219..02caea7f 100644 --- a/source/views/Popup/components/BurnXTC/hooks/useRequests.jsx +++ b/source/views/Popup/components/BurnXTC/hooks/useRequests.jsx @@ -42,7 +42,7 @@ const useRequests = (incomingRequests, callId, portId, transactionId) => { useEffect(async () => { if (requests.length === 0) { setLoading(true); - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); const success = await portRPC.call('handleRequestBurnXTC', [response, callId, portId, transactionId]); if (success) { window.close(); @@ -57,7 +57,7 @@ const useRequests = (incomingRequests, callId, portId, transactionId) => { const handleDeclineAll = async () => { const declinedRequests = requests.map((r) => ({ ...r, status: 'declined' })); - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); await portRPC.call('handleRequestBurnXTC', [declinedRequests, callId, portId, transactionId]); window.close(); }; diff --git a/source/views/Popup/components/ImportToken/index.jsx b/source/views/Popup/components/ImportToken/index.jsx index 4ba3e002..02238023 100644 --- a/source/views/Popup/components/ImportToken/index.jsx +++ b/source/views/Popup/components/ImportToken/index.jsx @@ -44,7 +44,7 @@ const ImportToken = ({ const handleImportToken = async (status) => { setLoading(status); - reviewPendingTransaction(transactionId, () => { }); + await reviewPendingTransaction(transactionId); const success = await portRPC.call('handleRequestImportToken', [ { status, token: { canisterId, standard, logo } }, callId, diff --git a/source/views/Popup/components/LoginProxy/index.jsx b/source/views/Popup/components/LoginProxy/index.jsx index 9158ab97..f9671880 100644 --- a/source/views/Popup/components/LoginProxy/index.jsx +++ b/source/views/Popup/components/LoginProxy/index.jsx @@ -16,7 +16,7 @@ const LoginProxy = ({ }) => { useEffect(async () => { if (metadata && callId && portId) { - await reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); await portRPC.call(handler, [metadata.url, args || {}, callId, portId, transactionId]); window.close(); } diff --git a/source/views/Popup/components/Principal/index.jsx b/source/views/Popup/components/Principal/index.jsx index 151250a9..a8076f86 100644 --- a/source/views/Popup/components/Principal/index.jsx +++ b/source/views/Popup/components/Principal/index.jsx @@ -16,7 +16,7 @@ const Principal = ({ }) => { useEffect(async () => { if (metadata && callId && portId) { - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); await portRPC.call('handleGetPrincipal', [metadata.url, callId, portId, transactionId]); window.close(); } diff --git a/source/views/Popup/components/Sign/components/BatchTransactions/hooks/useRPCTransactions.jsx b/source/views/Popup/components/Sign/components/BatchTransactions/hooks/useRPCTransactions.jsx index 4c5b2731..779b2326 100644 --- a/source/views/Popup/components/Sign/components/BatchTransactions/hooks/useRPCTransactions.jsx +++ b/source/views/Popup/components/Sign/components/BatchTransactions/hooks/useRPCTransactions.jsx @@ -33,7 +33,7 @@ const useTransactions = (transactions, callId, portId, transactionId) => { const processAll = async (accepted) => { setLoading(true); - reviewPendingTransaction(transactionId, (res) => res); + await reviewPendingTransaction(transactionId); await portRPC.call('handleBatchTransactions', [ accepted, transactions, diff --git a/source/views/Popup/components/Sign/hooks/useRequest.jsx b/source/views/Popup/components/Sign/hooks/useRequest.jsx index cab039f3..14e586cd 100644 --- a/source/views/Popup/components/Sign/hooks/useRequest.jsx +++ b/source/views/Popup/components/Sign/hooks/useRequest.jsx @@ -52,7 +52,7 @@ const useRequests = (incomingRequest, callId, portId, transactionId) => { const handleResponse = async (status) => { request.status = status; const handler = request.type === 'sign' ? 'handleSign' : 'handleCall'; - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); const success = await portRPC.call(handler, [status, request, callId, portId, transactionId]); if (success) { window.close(); diff --git a/source/views/Popup/components/Sign/hooks/useRequests.jsx b/source/views/Popup/components/Sign/hooks/useRequests.jsx index 1970aa4e..07ca7f57 100644 --- a/source/views/Popup/components/Sign/hooks/useRequests.jsx +++ b/source/views/Popup/components/Sign/hooks/useRequests.jsx @@ -40,7 +40,7 @@ const useRequests = (incomingRequests, callId, portId, transactionId) => { useEffect(async () => { if (requests.length === 0) { setLoading(true); - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); const success = await portRPC.call('handleSign', [response, callId, portId, transactionId]); if (success) { window.close(); @@ -55,7 +55,7 @@ const useRequests = (incomingRequests, callId, portId, transactionId) => { const handleDeclineAll = async () => { const declinedRequests = requests.map((r) => ({ ...r, status: 'declined' })); - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); await portRPC.call('handleSign', [declinedRequests, callId, portId, transactionId]); window.close(); }; diff --git a/source/views/Popup/components/SignMessage/index.jsx b/source/views/Popup/components/SignMessage/index.jsx index c5d34e0e..9d59abe7 100644 --- a/source/views/Popup/components/SignMessage/index.jsx +++ b/source/views/Popup/components/SignMessage/index.jsx @@ -46,7 +46,7 @@ const SignMessage = ({ const handleSignMessage = async (status) => { setLoading(status); - reviewPendingTransaction(transactionId, () => { }); + await reviewPendingTransaction(transactionId); const success = await portRPC.call('handleRequestSignMessage', [ { status, token: { canisterId, standard, logo }, messageToSign }, callId, diff --git a/source/views/Popup/components/Transfer/hooks/useRequests.jsx b/source/views/Popup/components/Transfer/hooks/useRequests.jsx index 7b9e8156..41dc6cd3 100644 --- a/source/views/Popup/components/Transfer/hooks/useRequests.jsx +++ b/source/views/Popup/components/Transfer/hooks/useRequests.jsx @@ -54,7 +54,7 @@ const useRequests = (incomingRequests, callId, portId, transactionId) => { if (requests.length === 0) { setLoading(true); const handler = response[0].token ? 'handleRequestTransferToken' : 'handleRequestTransfer'; - reviewPendingTransaction(transactionId, async () => {}); + await reviewPendingTransaction(transactionId); const success = await portRPC.call(handler, [response, callId, portId, transactionId]); if (success) { window.close(); @@ -71,8 +71,8 @@ const useRequests = (incomingRequests, callId, portId, transactionId) => { const declinedRequests = requests.map((r) => ({ ...r, status: 'declined' })); const handler = declinedRequests[0].token ? 'handleRequestTransferToken' : 'handleRequestTransfer'; await Promise.all([ - reviewPendingTransaction(transactionId, async () => {}), - portRPC.call(handler, [declinedRequests, callId, portId, transactionId]), + await reviewPendingTransaction(transactionId), + await portRPC.call(handler, [declinedRequests, callId, portId, transactionId]), ]); window.close(); From 7bd68e3e7dee544fa1232692aeedd043785cc27e Mon Sep 17 00:00:00 2001 From: rocky-fleek Date: Sat, 3 Dec 2022 18:34:06 -0600 Subject: [PATCH 2/2] Removed console.log --- source/Modules/Controller/transaction.js | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Modules/Controller/transaction.js b/source/Modules/Controller/transaction.js index e9d34cbb..9ead5049 100644 --- a/source/Modules/Controller/transaction.js +++ b/source/Modules/Controller/transaction.js @@ -441,7 +441,6 @@ export class TransactionModule extends ControllerModuleBase { return { methodName: 'requestCall', handler: async (opts, metadata, args, batchTxId, decodedArgs, transactionId) => { - console.log('calling requestCall', transactionId); const { message, sender, callback } = opts; const { id: callId } = message.data.data; const { id: portId } = sender;