Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.

(Feature) [Spending Limits] Transaction List details#1271

Merged
mmv08 merged 24 commits intofeature/#413-SpendingLimit-in-appfrom
feature/#691-txList-SpendingLimit
Sep 9, 2020
Merged

(Feature) [Spending Limits] Transaction List details#1271
mmv08 merged 24 commits intofeature/#413-SpendingLimit-in-appfrom
feature/#691-txList-SpendingLimit

Conversation

@fernandomg
Copy link
Contributor

@fernandomg fernandomg commented Aug 25, 2020

This PR closes #691, by:

  • identifying and displaying tx details for Spending Limit txs

  • also displays hex data for those txs that don't have decodedData and wraps its content to avoid overflow of text:

@fernandomg fernandomg self-assigned this Aug 25, 2020
@fernandomg fernandomg marked this pull request as draft August 25, 2020 12:34
@github-actions
Copy link

CLA Assistant Lite All Contributors have signed the CLA.

@github-actions
Copy link

github-actions bot commented Aug 25, 2020

ESLint Summary View Full Report

Annotations are provided inline on the Files Changed tab. You can also see all annotations that were generated on the annotations page.

Type Occurrences Fixable
Errors 0 0
Warnings 9 0
Ignored 5 N/A
  • Result: ✅ success

  • Annotations: 9 total


[warning] @typescript-eslint/explicit-module-boundary-types

Require explicit return and argument types on exported functions' and classes' public class methods


[warning] @typescript-eslint/no-non-null-assertion

Disallows non-null assertions using the ! postfix operator


Report generated by eslint-plus-action

@ghost
Copy link

ghost commented Aug 25, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

2 similar comments
@ghost
Copy link

ghost commented Aug 25, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

@ghost
Copy link

ghost commented Aug 26, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

@fernandomg fernandomg marked this pull request as ready for review August 28, 2020 23:52
@ghost
Copy link

ghost commented Aug 29, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

@github-actions
Copy link

github-actions bot commented Sep 1, 2020

ESLint Summary View Full Report

Annotations are provided inline on the Files Changed tab. You can also see all annotations that were generated on the annotations page.

Type Occurrences Fixable
Errors 0 0
Warnings 10 0
Ignored 4 N/A
  • Result: ✅ success

  • Annotations: 10 total


[warning] @typescript-eslint/explicit-module-boundary-types

Require explicit return and argument types on exported functions' and classes' public class methods


[warning] @typescript-eslint/no-non-null-assertion

Disallows non-null assertions using the ! postfix operator


Report generated by eslint-plus-action

@ghost
Copy link

ghost commented Sep 1, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

EXECUTE_ALLOWANCE_TRANSFER: 'executeAllowanceTransfer',
}

export const SPENDING_LIMIT_METHOD_TO_ID = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like id to a method, because the keys are IDs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that messed with my head too. That means that the METHOD_TO_ID const for Safe's methods, should be renamed as well. Isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored a bit, moved these objects to the type file and renamed


const moduleTransactions = await loadModuleTransactions(safeAddress)

if (moduleTransactions) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default response for this is [], I think you wanted to check .length

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks

Comment on lines +24 to +34
const state = store.getState()

if (!safeAddress) {
return defaultResponse
}

const safe = state[SAFE_REDUCER_ID].getIn(['safes', safeAddress])

if (!safe) {
return defaultResponse
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we accessing state in a function whose responsibility is just to fetch transactions from the backend?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to access it, thanks

@@ -0,0 +1,32 @@
import { handleActions } from 'redux-actions'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need a separate reducer? what was wrong with the previous one we used for transactions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a different endpoint, and the returned data is quite different. Same strategy as with incomingTransactions

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in the end, we get to merge them to a single list

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in the end, we get to merge them to a single list

yes, but closer to the component.

Fortunately, this will work differently with the allTransactions endpoint approach.

In fact, I explored the strategy of storing the plain DTO in the store and then calculate data in the selector, it ended up working quite decently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then should've gone for it 👍

const oldModuleTxs = state[safeAddress] ?? []
const oldModuleTxsHashes = oldModuleTxs.map(({ transactionHash }) => transactionHash)
// filtering in this level happens, because backend is returning the whole list of txs
// so, to avoid re-storing all the txs, those already stored are filtered out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does it matter if we restore them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is not the "re-store", but the duplicates

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, I would change the comment "to avoid duplicates..."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed

const txToken = tokens.find((token) => token.address === tx.token)
const isSendingETH = txToken.address === ETH_ADDRESS
const txRecipient = isSendingETH ? tx.recipientAddress : txToken.address
const txToken = React.useMemo(() => tokens.find((token) => token.address === tx.token), [tokens, tx.token])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tx.token is an object, will equality check for this case? if tx changes then it will be re-run I think

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to double-check this, it's a string:

notifiedTransaction: TX_NOTIFICATION_TYPES.STANDARD_TX,
enqueueSnackbar,
closeSnackbar,
} as any),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to remove as any? createTransaction method is typed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also it's now not needed to pass closeSnackbar/enqueueSnackbar

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, removed and fixed

</Paragraph>
<ButtonLink
onClick={() => mutators.setMax(selectedTokenRecord.balance)}
onClick={() =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The component is getting really big, would be good to split it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{(sortedData) =>
sortedData.map((row, index) => (
<React.Fragment key={index}>
<React.Fragment key={`${row.tx.safeTxHash}-${index}`}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The index is not required in that case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops! fixed, thanks

}

return getTransactionTableData(tx, cancelTxs.get(`${tx.nonce}`))
return getTransactionTableData(tx as Transaction, cancelTxs.get(`${tx.nonce}`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was the error there that required as?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTransactionTableData has issues with tx being of SafeModuleTransaction type.

I tried helping TS by using type guards, but it didn't work either: https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we should explore using type guards, this is getting a problem for tokens also

@ghost
Copy link

ghost commented Sep 3, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

1 similar comment
@ghost
Copy link

ghost commented Sep 3, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

@fernandomg fernandomg requested a review from mmv08 September 3, 2020 18:03
@ghost
Copy link

ghost commented Sep 3, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

@ghost
Copy link

ghost commented Sep 3, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

Copy link
Contributor

@mmv08 mmv08 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address those small changes before merging, otherwise good job :)

export const isSetAllowanceMethod = (data: string): boolean => {
const methodId = data.slice(0, 10) as keyof typeof SPENDING_LIMIT_METHOD_TO_ID
return SPENDING_LIMIT_METHOD_TO_ID[methodId] === SPENDING_LIMIT_METHODS_NAMES.SET_ALLOWANCE
const methodId = data.slice(0, 10) as keyof typeof SPENDING_LIMIT_METHOD_ID_TO_NAME
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to export this keyof typeof thing to a separate type

const moduleTransactions = await loadModuleTransactions(safeAddress)

if (moduleTransactions.length) {
dispatch(addModuleTransactions({ modules: moduleTransactions, safeAddress }))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Little inconsistency in naming, transactions get passed as modules

@@ -0,0 +1,32 @@
import { handleActions } from 'redux-actions'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then should've gone for it 👍

}

return getTransactionTableData(tx, cancelTxs.get(`${tx.nonce}`))
return getTransactionTableData(tx as Transaction, cancelTxs.get(`${tx.nonce}`))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we should explore using type guards, this is getting a problem for tokens also

@francovenica
Copy link
Contributor

https://pr1271--safereact.review.gnosisdev.com/app/#/safes/0x9913B9180C20C6b0F21B6480c84422F6ebc4B808/transactions
The user that has the spending limit 0x6E45d69a383CECa3d54688e833Bd0e1388747e6B

If I open a tx "Spending limit" created by sending funds using the user with the spending limit I get a console error and the page crashes
image.png

@francovenica
Copy link
Contributor

francovenica commented Sep 4, 2020

Minor issue:
When changing the checkbox to choose between a regular transaction or using spending limit the amount should be checked if it is valid
https://www.loom.com/share/743778ae0373493a8245e534c5ae70ab

EDIT:
It seems that's the way the form works, this issue is also present if you set an amount, and then change tokens that has less than the amount that was input previously
image.png

The system will not let you send more tokens than you have in the safe so is not critical.

…List-SpendingLimit

# Conflicts:
#	src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions.ts
#	src/logic/safe/store/selectors/index.ts
#	src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx
#	src/routes/safe/components/Transactions/TxsTable/ExpandedTxRow/TxDescription/CustomDescription.tsx
#	src/routes/safe/components/Transactions/TxsTable/columns.tsx
#	src/routes/safe/components/Transactions/TxsTable/index.tsx
@fernandomg
Copy link
Contributor Author

@francovenica, thanks for the catch. Now ETH spending limit txs are properly displayed.

@ghost
Copy link

ghost commented Sep 8, 2020

Travis automatic deployment:
https://pr1271--safereact.review.gnosisdev.com/app

@mmv08 mmv08 merged commit 9936794 into feature/#413-SpendingLimit-in-app Sep 9, 2020
@mmv08 mmv08 deleted the feature/#691-txList-SpendingLimit branch September 9, 2020 12:16
@github-actions github-actions bot locked and limited conversation to collaborators Sep 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants