add processTransaction action

This commit is contained in:
Mikhail Mikheev 2019-07-05 19:43:36 +04:00
parent d16f79f289
commit 87c41e4d78
9 changed files with 67 additions and 19 deletions

View File

@ -61,13 +61,27 @@ export const executeTransaction = async (
operation: Operation,
nonce: string | number,
sender: string,
signatures?: string,
) => {
console.log({
to,
valueInWei,
data,
operation,
nonce,
sender,
signatures,
})
try {
let sigs = signatures
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
const sigs = `0x000000000000000000000000${sender.replace(
'0x',
'',
)}000000000000000000000000000000000000000000000000000000000000000001`
if (!sigs) {
sigs = `0x000000000000000000000000${sender.replace(
'0x',
'',
)}000000000000000000000000000000000000000000000000000000000000000001`
}
const receipt = await safeInstance.execTransaction(
to,

View File

@ -34,6 +34,7 @@ type Props = SelectorProps & {
granted: boolean,
updateSafe: Function,
createTransaction: Function,
processTransaction: Function,
fetchTransactions: Function,
}
@ -104,6 +105,7 @@ class Layout extends React.Component<Props, State> {
tokens,
activeTokens,
createTransaction,
processTransaction,
fetchTransactions,
updateSafe,
transactions,
@ -169,6 +171,7 @@ class Layout extends React.Component<Props, State> {
userAddress={userAddress}
granted={granted}
createTransaction={createTransaction}
processTransaction={processTransaction}
/>
)}
{tabIndex === 2 && (

View File

@ -20,10 +20,11 @@ type Props = {
onClose: () => void,
classes: Object,
isOpen: boolean,
createTransaction: Function,
processTransaction: Function,
tx: Transaction,
nonce: string,
safeAddress: string,
threshold: number,
thresholdReached: boolean,
}
@ -42,10 +43,18 @@ const getModalTitleAndDescription = (thresholdReached: boolean) => {
}
const ApproveTxModal = ({
onClose, isOpen, classes, createTransaction, tx, safeAddress, thresholdReached,
onClose,
isOpen,
classes,
processTransaction,
tx,
safeAddress,
threshold,
thresholdReached,
}: Props) => {
const [shouldExecuteTx, setShouldExecuteTx] = useState<boolean>(false)
const { title, description } = getModalTitleAndDescription(thresholdReached)
const oneConfirmationLeft = tx.confirmations.size + 1 === threshold
const handleExecuteCheckbox = () => setShouldExecuteTx(prevShouldExecute => !prevShouldExecute)
@ -53,14 +62,7 @@ const ApproveTxModal = ({
<SharedSnackbarConsumer>
{({ openSnackbar }) => {
const approveTx = () => {
createTransaction(
safeAddress,
tx.recipient,
tx.value,
tx.data,
openSnackbar,
thresholdReached || shouldExecuteTx,
)
processTransaction(safeAddress, tx, openSnackbar, thresholdReached || shouldExecuteTx)
onClose()
}
@ -83,7 +85,7 @@ const ApproveTxModal = ({
<br />
<Bold className={classes.nonceNumber}>{tx.nonce}</Bold>
</Paragraph>
{!thresholdReached && (
{!thresholdReached && oneConfirmationLeft && (
<>
<Paragraph color="error">
Approving transaction does not execute it immediately. If you want to approve and execute the

View File

@ -37,6 +37,7 @@ type Props = {
userAddress: string,
safeAddress: string,
createTransaction: Function,
processTransaction: Function,
}
type OpenModal = 'cancelTx' | 'approveTx' | null
@ -55,7 +56,6 @@ const txStatusToLabel = {
const isCancellationTransaction = (tx: Transaction, safeAddress: string) => !tx.value && tx.data === EMPTY_DATA && tx.recipient === safeAddress
const ExpandedTx = ({
classes,
tx,
@ -65,6 +65,7 @@ const ExpandedTx = ({
userAddress,
safeAddress,
createTransaction,
processTransaction,
}: Props) => {
const [tabIndex, setTabIndex] = useState<number>(0)
const [openModal, setOpenModal] = useState<OpenModal>(null)
@ -74,7 +75,7 @@ const ExpandedTx = ({
const cancellationTx = isCancellationTransaction(tx, safeAddress)
const confirmedLabel = `Confirmed [${tx.confirmations.size}/${threshold}]`
const unconfirmedLabel = `Unconfirmed [${owners.size - tx.confirmations.size}]`
const thresholdReached = owners.size <= tx.confirmations.size
const thresholdReached = threshold <= tx.confirmations.size
const ownersWhoConfirmed = []
const ownersUnconfirmed = []
@ -195,11 +196,13 @@ to:
/>
<ApproveTxModal
isOpen={openModal === 'approveTx'}
createTransaction={createTransaction}
processTransaction={processTransaction}
onClose={closeModal}
tx={tx}
safeAddress={safeAddress}
threshold={threshold}
thresholdReached={thresholdReached}
currentUserAlreadyConfirmed={currentUserAlreadyConfirmed}
/>
</>
)

View File

@ -36,6 +36,7 @@ type Props = {
granted: boolean,
safeAddress: string,
createTransaction: Function,
processTransaction: Function,
}
const TxsTable = ({
@ -47,6 +48,7 @@ const TxsTable = ({
userAddress,
safeAddress,
createTransaction,
processTransaction,
}: Props) => {
const [expandedTx, setExpandedTx] = useState<string | null>(null)
@ -113,6 +115,7 @@ const TxsTable = ({
granted={granted}
userAddress={userAddress}
createTransaction={createTransaction}
processTransaction={processTransaction}
safeAddress={safeAddress}
/>
</TableCell>

View File

@ -15,6 +15,7 @@ type Props = {
userAddress: string,
granted: boolean,
createTransaction: Function,
processTransaction: Function,
}
const Transactions = ({
@ -25,6 +26,7 @@ const Transactions = ({
granted,
safeAddress,
createTransaction,
processTransaction,
fetchTransactions,
}: Props) => {
useEffect(() => {
@ -44,6 +46,7 @@ const Transactions = ({
granted={granted}
safeAddress={safeAddress}
createTransaction={createTransaction}
processTransaction={processTransaction}
/>
) : (
<NoTransactions />

View File

@ -2,6 +2,7 @@
import fetchSafe from '~/routes/safe/store/actions/fetchSafe'
import fetchTokenBalances from '~/routes/safe/store/actions/fetchTokenBalances'
import createTransaction from '~/routes/safe/store/actions/createTransaction'
import processTransaction from '~/routes/safe/store/actions/processTransaction'
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
import updateSafe from '~/routes/safe/store/actions/updateSafe'
import fetchTokens from '~/logic/tokens/store/actions/fetchTokens'
@ -13,12 +14,14 @@ export type Actions = {
fetchTransactions: typeof fetchTransactions,
updateSafe: typeof updateSafe,
fetchTokens: typeof fetchTokens,
processTransaction: typeof processTransaction,
}
export default {
fetchSafe,
fetchTokenBalances,
createTransaction,
processTransaction,
fetchTokens,
fetchTransactions,
updateSafe,

View File

@ -63,6 +63,7 @@ class SafeView extends React.Component<Props> {
network,
tokens,
createTransaction,
processTransaction,
fetchTransactions,
updateSafe,
transactions,
@ -79,6 +80,7 @@ class SafeView extends React.Component<Props> {
network={network}
granted={granted}
createTransaction={createTransaction}
processTransaction={processTransaction}
fetchTransactions={fetchTransactions}
updateSafe={updateSafe}
transactions={transactions}

View File

@ -7,6 +7,20 @@ import { type GlobalState } from '~/store'
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
import { approveTransaction, executeTransaction, CALL } from '~/logic/safe/transactions'
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
// https://github.com/gnosis/safe-contracts/blob/master/test/gnosisSafeTeamEdition.js#L26
const generateSignaturesFromTxConfirmations = (tx: Transaction) => {
let sigs = '0x'
tx.confirmations.forEach((conf) => {
sigs
+= `000000000000000000000000${
conf.owner.address.replace('0x', '')
}0000000000000000000000000000000000000000000000000000000000000000`
+ '01'
})
return sigs
}
const processTransaction = (
safeAddress: string,
tx: Transaction,
@ -18,11 +32,12 @@ const processTransaction = (
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
const from = userAccountSelector(state)
const nonce = (await safeInstance.nonce()).toString()
const sigs = generateSignaturesFromTxConfirmations(tx)
let txHash
if (shouldExecute) {
openSnackbar('Transaction has been submitted', 'success')
txHash = await executeTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from)
txHash = await executeTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from, sigs)
openSnackbar('Transaction has been confirmed', 'success')
} else {
openSnackbar('Approval transaction has been submitted', 'success')