Skip to content

Commit

Permalink
Merge pull request #50 from gnosis/transaction-translations
Browse files Browse the repository at this point in the history
Transaction translations
  • Loading branch information
jfschwarz authored Jan 17, 2023
2 parents 47a4792 + e1c327e commit f4de141
Show file tree
Hide file tree
Showing 18 changed files with 1,142 additions and 656 deletions.
2 changes: 2 additions & 0 deletions extension/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"alchemix",
"apikey",
"barnbridge",
"Blockhash",
"blockie",
"blockies",
"borderless",
Expand All @@ -20,6 +21,7 @@
"iframes",
"instadapp",
"mastercopy",
"multicall",
"multisend",
"Omni",
"outdir",
Expand Down
26 changes: 13 additions & 13 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,22 @@
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@types/react-modal": "^3.13.1",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@typescript-eslint/eslint-plugin": "^5.48.1",
"@typescript-eslint/parser": "^5.48.1",
"@walletconnect/ethereum-provider": "^1.8.0",
"classnames": "^2.3.1",
"copy-to-clipboard": "^3.3.1",
"cspell": "^5.13.0",
"dotenv": "^16.0.1",
"esbuild": "^0.13.14",
"esbuild-css-modules-plugin": "^2.0.9",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"esbuild": "^0.16.17",
"esbuild-css-modules-plugin": "^2.7.0",
"eslint": "^8.31.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-import": "^2.27.4",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.0",
"eslint-plugin-react-hooks": "^4.6.0",
"ethereum-blockies-base64": "^1.0.2",
"ethers": "^5.7.2",
"ethers-proxies": "^1.0.0",
Expand All @@ -62,8 +62,8 @@
"isomorphic-fetch": "^3.0.0",
"jest": "^27.4.5",
"nanoid": "^3.1.30",
"node-stdlib-browser": "^1.1.0",
"prettier": "^2.4.1",
"node-stdlib-browser": "^1.2.0",
"prettier": "^2.8.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.3.1",
Expand All @@ -74,7 +74,7 @@
"rimraf": "^3.0.2",
"ts-jest": "^27.1.2",
"typechain": "^8.0.0",
"typescript": "^4.7.4",
"typescript": "^4.9.4",
"typescript-plugin-css-modules": "^3.4.0"
}
}
44 changes: 44 additions & 0 deletions extension/src/browser/Drawer/CopyToClipboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react'
import { RiFileCopy2Line } from 'react-icons/ri'
import { encodeSingle, TransactionInput } from 'react-multisend'
import { toast } from 'react-toastify'

import { IconButton } from '../../components'

import classes from './style.module.css'

interface Props {
transaction: TransactionInput
labeled?: boolean
}

const CopyToClipboard: React.FC<Props> = ({ transaction, labeled }) => {
const encodedTransaction = encodeSingle(transaction)

const copyToClipboard = () => {
navigator.clipboard.writeText(
JSON.stringify(encodedTransaction, undefined, 2)
)
toast(<>Transaction data has been copied to clipboard.</>)
}

if (labeled) {
return (
<button onClick={copyToClipboard} className={classes.link}>
Copy data
<RiFileCopy2Line />
</button>
)
} else {
return (
<IconButton
onClick={copyToClipboard}
title="Copy transaction data to clipboard"
>
<RiFileCopy2Line />
</IconButton>
)
}
}

export default CopyToClipboard
73 changes: 73 additions & 0 deletions extension/src/browser/Drawer/Remove.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react'
import { RiDeleteBinLine } from 'react-icons/ri'
import { encodeSingle, TransactionInput } from 'react-multisend'

import { IconButton } from '../../components'
import { ForkProvider } from '../../providers'
import { useConnection } from '../../settings'
import { useProvider } from '../ProvideProvider'
import { useDispatch, useNewTransactions } from '../state'

import { formatValue } from './formatValue'
import classes from './style.module.css'

type Props = {
transaction: TransactionInput
index: number
}

export const Remove: React.FC<Props> = ({ transaction, index }) => {
const provider = useProvider()
const dispatch = useDispatch()
const transactions = useNewTransactions()
const { connection } = useConnection()

if (!(provider instanceof ForkProvider)) {
// Removing transactions is only supported when using ForkProvider
return null
}

const handleRemove = async () => {
const laterTransactions = transactions.slice(index + 1)

// remove the transaction and all later ones from the store
dispatch({ type: 'REMOVE_TRANSACTION', payload: { id: transaction.id } })

if (transactions.length === 1) {
// no more recorded transaction remains: we can delete the fork and will create a fresh one once we receive the next transaction
await provider.deleteFork()
return
}

// revert to checkpoint before the transaction to remove
const checkpoint = transaction.id // the ForkProvider uses checkpoints as IDs for the recorded transactions
await provider.request({ method: 'evm_revert', params: [checkpoint] })

// re-simulate all transactions after the removed one
for (let i = 0; i < laterTransactions.length; i++) {
const transaction = laterTransactions[i]
const encoded = encodeSingle(transaction.input)
await provider.request({
method: 'eth_sendTransaction',
params: [
{
to: encoded.to,
data: encoded.data,
value: formatValue(encoded.value),
from: connection.avatarAddress,
},
],
})
}
}

return (
<IconButton
onClick={handleRemove}
className={classes.removeTransaction}
title="Remove transaction"
>
<RiDeleteBinLine />
</IconButton>
)
}
34 changes: 16 additions & 18 deletions extension/src/browser/Drawer/RolePermissionCheck.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
import React from 'react'
import { useEffect, useState } from 'react'
import { RiFileCopy2Line, RiGroupLine } from 'react-icons/ri'
import { RiGroupLine } from 'react-icons/ri'
import { encodeSingle, TransactionInput } from 'react-multisend'
import { toast } from 'react-toastify'

import { Flex, Tag } from '../../components'
import { findApplicableTranslation } from '../../transactionTranslations'
import { JsonRpcError } from '../../types'
import { decodeRolesError } from '../../utils'
import { isPermissionsError } from '../../utils/decodeRolesError'
import { useWrappingProvider } from '../ProvideProvider'

import CopyToClipboard from './CopyToClipboard'
import { Translate } from './Translate'
import classes from './style.module.css'

const RolePermissionCheck: React.FC<{
transaction: TransactionInput
index: number
mini?: boolean
}> = ({ transaction, mini = false }) => {
}> = ({ transaction, index, mini = false }) => {
const [error, setError] = useState<string | undefined | false>(undefined)
const wrappingProvider = useWrappingProvider()

const transactionEncoded = encodeSingle(transaction)
const encodedTransaction = encodeSingle(transaction)

const translationAvailable = !!findApplicableTranslation(encodedTransaction)

useEffect(() => {
let canceled = false
wrappingProvider
.request({
method: 'eth_estimateGas',
params: [transactionEncoded],
params: [encodedTransaction],
})
.then(() => {
if (!canceled) setError(false)
Expand All @@ -41,14 +46,7 @@ const RolePermissionCheck: React.FC<{
return () => {
canceled = true
}
}, [wrappingProvider, transactionEncoded])

const copyToClipboard = () => {
navigator.clipboard.writeText(
JSON.stringify(transactionEncoded, undefined, 2)
)
toast(<>Transaction data has been copied to clipboard.</>)
}
}, [wrappingProvider, encodedTransaction])

if (error === undefined) return null

Expand Down Expand Up @@ -86,11 +84,11 @@ const RolePermissionCheck: React.FC<{
)}
</Flex>
</Flex>
{error && (
<button onClick={copyToClipboard} className={classes.link}>
Copy data
<RiFileCopy2Line />
</button>
{error && translationAvailable && (
<Translate transaction={transaction} index={index} labeled />
)}
{error && !translationAvailable && (
<CopyToClipboard transaction={transaction} labeled />
)}
</Flex>
</Flex>
Expand Down
Loading

0 comments on commit f4de141

Please sign in to comment.