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

Development v2 fixes #822

Merged
merged 51 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
94a56d2
Bug: Invalid V in signature with eth_sign (#728)
mmv08 Apr 3, 2020
727b164
BUG: Only injected providers are cached as last used provider (#733)
mmv08 Apr 3, 2020
ba49c97
(Fix) Adapt app to back-end changes (#736)
fernandomg Apr 6, 2020
0441ce2
(Fix) Transaction not automatically executed (#716)
fernandomg Apr 6, 2020
e33d9fd
(Fix) Change the order of the upgrade methods lookup (#740)
fernandomg Apr 7, 2020
b8bfeab
Feature: Use eth_sign for hardware wallets connected via onboard.js (…
mmv08 Apr 8, 2020
fbc3696
update package json (#743)
mmv08 Apr 8, 2020
fc68f70
Merge branch 'master' of github.com:gnosis/safe-react into development
mmv08 Apr 8, 2020
d2f81fc
Merge branch 'development' of github.com:gnosis/safe-react into devel…
mmv08 Apr 8, 2020
1ac13c6
(Fix) Properly decode threshold value in tx details (#749)
fernandomg Apr 9, 2020
b0849ee
fix: check for `decimals` method in transferredTokens (#748)
fernandomg Apr 9, 2020
b1f50c7
Bug #747: Don't use getLastTxNonce to fetch safe nonce (#750)
mmv08 Apr 9, 2020
4bfe937
Merge branch 'master' of github.com:gnosis/safe-react into development
mmv08 Apr 9, 2020
19dc933
Issue-595: Apps config from Manifest (#715)
nicosampler Apr 9, 2020
c40fa07
(Fix) If backend returns `null` for addresses the Transaction ca… (#718)
fernandomg Apr 13, 2020
6bdbcd2
#751 fix - Replaces decimals from backend with decimals from blockcha…
Agupane Apr 14, 2020
a18513a
Added Unilogin provider + support for legacy paths (#719)
matextrem Apr 16, 2020
dd85d4a
fallback to displaying custom tx when we fail to fetch token info (#767)
mmv08 Apr 16, 2020
4956f0e
Merge branch 'master' of github.com:gnosis/safe-react into development
mmv08 Apr 16, 2020
7da0e94
Create release.yml
matextrem Apr 16, 2020
2e5d156
Merge pull request #774 from gnosis/feature/release-script
matextrem Apr 16, 2020
204edd6
Feature #322: Set safeTxGas for newly created transactions (#752)
mmv08 Apr 20, 2020
8ba0e18
Manage Apps (#765)
nicosampler Apr 21, 2020
035882e
fix scroll and fix margin layout
alongoni Apr 22, 2020
66dc954
Add region to travis CI develop (#787)
davizalpe Apr 22, 2020
aee2a1f
Feature/travis ci s3 region (#789)
davizalpe Apr 22, 2020
c5a1e40
Merge branch 'development' into issue-773
alongoni Apr 22, 2020
124a917
fix error on Wrapper
alongoni Apr 22, 2020
38eb8ab
Add gnosis wc bridge to onboard.js wallets options array (#790)
mmv08 Apr 22, 2020
85f65f6
Merge pull request #791 from gnosis/issue-773
alongoni Apr 22, 2020
c0422bd
Rename incoming-transactions url to incoming-transfers
Uxio0 Apr 23, 2020
9d78492
Feature #587 - App performance improvement (#738)
Agupane Apr 23, 2020
162ff84
Fix (#777)
nicosampler Apr 24, 2020
0cd526f
fix: batchRequest params order
fernandomg Apr 23, 2020
edcfd2e
fix: execute decodeParams for all sendTokenTxs
fernandomg Apr 23, 2020
b46af65
fix: proper amount display for tx in TxTable
fernandomg Apr 23, 2020
d91f403
Uses formatAmount
Agupane Apr 24, 2020
75418eb
Removes unused code
Agupane Apr 23, 2020
8da025c
Fixs composeValidators
Agupane Apr 23, 2020
74d9ce7
Makes composeValidatorsApps a wrapper
Agupane Apr 24, 2020
5cbb8f5
Moves composeValidatorsApps to managesApps.js
Agupane Apr 24, 2020
c57885d
Desktop app (#745)
matextrem Apr 24, 2020
22f31b1
Merge branch 'master' of github.com:gnosis/safe-react into development
mmv08 Apr 24, 2020
281c3c6
Update yarn script + SAFE_APPS env variable
matextrem Apr 24, 2020
8c91e02
Merge pull request #808 from gnosis/fix/release-apps
matextrem Apr 24, 2020
f4cca4c
Converts custom token address to checksum version (#793)
Agupane Apr 27, 2020
76c673a
SafeTxGas calculation: Add check for openethereum/parity revert messa…
mmv08 Apr 27, 2020
5014e86
Issue 796 (#807)
nicosampler Apr 27, 2020
653f68b
(Feature) Tx Table amount notations (#812)
fernandomg Apr 27, 2020
9363485
Fix master conflicts (#819)
nicosampler Apr 27, 2020
1388daa
Merge branch 'development' into development-v2
nicosampler Apr 27, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@
},
"dependencies": {
"@gnosis.pm/safe-contracts": "1.1.1-dev.2",
"@gnosis.pm/util-contracts": "2.0.6",
"@ledgerhq/hw-transport-node-hid": "5.12.0",
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#71e6fed",
"@gnosis.pm/util-contracts": "2.0.6",
"@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#a057248",
"@ledgerhq/hw-transport-node-hid": "5.12.0",
"@material-ui/core": "4.9.10",
"@material-ui/icons": "4.9.1",
"@material-ui/lab": "4.0.0-alpha.39",
Expand Down
3 changes: 2 additions & 1 deletion src/components-v2/layouts/ListContentLayout/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import styled from 'styled-components'
export const Wrapper = styled.div`
display: grid;
grid-template-columns: 245px auto;
grid-template-rows: 500px;
grid-template-rows: 514px;
min-height: 525px;

.background {
Expand Down Expand Up @@ -33,6 +33,7 @@ export const Menu = styled.div.attrs(() => ({ className: 'background' }))`
export const Content = styled.div.attrs(() => ({ className: 'background' }))`
grid-column: 2;
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
background-color: white;
`

Expand Down
9 changes: 8 additions & 1 deletion src/logic/safe/transactions/gasNew.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,15 @@ export const estimateSafeTxGas = async (
gasLimit: txGasEstimation + dataGasEstimation + additionalGas,
},
(error, res) => {
// res.data check is for OpenEthereum/Parity revert messages format
const isOpenEthereumRevertMsg = res && typeof res.data === 'string'

const isEstimationSuccessful =
!error &&
((typeof res === 'string' && res !== '0x') || (isOpenEthereumRevertMsg && res.data.slice(9) !== '0x'))

resolve({
success: error || res === '0x' ? false : true,
success: isEstimationSuccessful,
estimation: txGasEstimation + additionalGas,
})
},
Expand Down
2 changes: 1 addition & 1 deletion src/logic/tokens/store/reducer/tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { type Token, makeToken } from '~/logic/tokens/store/model/token'

export const TOKEN_REDUCER_ID = 'tokens'

export type State = Map<string, Map<string, Token>>
export type State = Map<string, Token>

export default handleActions<State, *>(
{
Expand Down
2 changes: 1 addition & 1 deletion src/logic/tokens/utils/formatAmount.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const formatAmount = (number: string | number) => {
let numberFloat = parseFloat(number)

if (numberFloat === 0) {
numberFloat = '0.000'
numberFloat = '0'
} else if (numberFloat < 0.001) {
numberFloat = '< 0.001'
} else if (numberFloat < 1000) {
Expand Down
5 changes: 3 additions & 2 deletions src/routes/safe/components/Apps/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const APPS_STORAGE_KEY = 'APPS_STORAGE_KEY'
const APPS_LEGAL_DISCLAIMER_STORAGE_KEY = 'APPS_LEGAL_DISCLAIMER_STORAGE_KEY'

const StyledIframe = styled.iframe`
padding: 24px;
box-sizing: border-box;
width: 100%;
height: 100%;
display: ${(props) => (props.shouldDisplay ? 'block' : 'none')};
Expand All @@ -36,7 +38,6 @@ const Centered = styled.div`
justify-content: center;
flex-direction: column;
`

const operations = {
SEND_TRANSACTIONS: 'SEND_TRANSACTIONS',
ON_SAFE_INFO: 'ON_SAFE_INFO',
Expand Down Expand Up @@ -151,7 +152,7 @@ function Apps({ closeModal, closeSnackbar, enqueueSnackbar, openModal }: Props)
<a href="https://gnosis-safe.io/terms" rel="noopener noreferrer" target="_blank">
Terms
</a>{' '}
and this Disclaimer, and agree to be bound by .
and this Disclaimer, and agree to be bound by them.
</Text>
</>
}
Expand Down
18 changes: 12 additions & 6 deletions src/routes/safe/components/Apps/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import axios from 'axios'

import appsIconSvg from '~/routes/safe/components/Transactions/TxsTable/TxType/assets/appsIcon.svg'

export const GNOSIS_APPS_URL = 'https://gnosis-apps.netlify.app'

const appsUrl = process.env.REACT_APP_GNOSIS_APPS_URL ? process.env.REACT_APP_GNOSIS_APPS_URL : GNOSIS_APPS_URL
export const staticAppsList = [{ url: `${appsUrl}/compound`, disabled: false }]
export const staticAppsList = [
{ url: `${process.env.REACT_APP_GNOSIS_APPS_URL}/compound`, disabled: false },
{ url: `${process.env.REACT_APP_GNOSIS_APPS_URL}/uniswap`, disabled: false },
{ url: `${process.env.REACT_APP_GNOSIS_APPS_URL}/nexus-mutual`, disabled: false },
{ url: `${process.env.REACT_APP_GNOSIS_APPS_URL}/ens`, disabled: false },
]

export const getAppInfoFromOrigin = (origin: string) => {
try {
Expand All @@ -18,13 +20,17 @@ export const getAppInfoFromOrigin = (origin: string) => {
}

export const getAppInfoFromUrl = async (appUrl: string) => {
let res = { id: undefined, url: cleanedUpAppUrl, name: 'unknown', iconUrl: appsIconSvg, error: true }

if (!appUrl) {
return res
}

let cleanedUpAppUrl = appUrl.trim()
if (cleanedUpAppUrl.substr(-1) === '/') {
cleanedUpAppUrl = cleanedUpAppUrl.substr(0, cleanedUpAppUrl.length - 1)
}

let res = { id: undefined, url: cleanedUpAppUrl, name: 'unknown', iconUrl: appsIconSvg, error: true }

try {
const appInfo = await axios.get(`${cleanedUpAppUrl}/manifest.json`)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Img from '~/components/layout/Img'
import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row'
import { type Token, type TokenProps } from '~/logic/tokens/store/model/token'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import TokenPlaceholder from '~/routes/safe/components/Balances/assets/token_placeholder.svg'

export const ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID = 'add-custom-token-address-input'
Expand Down Expand Up @@ -64,8 +65,9 @@ const AddCustomToken = (props: Props) => {
const [formValues, setFormValues] = useState(INITIAL_FORM_STATE)

const handleSubmit = (values) => {
const address = getWeb3().utils.toChecksumAddress(values.address)
const token = {
address: values.address,
address,
decimals: values.decimals,
symbol: values.symbol,
name: values.symbol,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const IncomingTxDescription = ({ tx }: Props) => {
const txFromName = getNameFromAddressBook(tx.from)
return (
<Block className={classes.txDataContainer}>
<TransferDescription from={tx.from} txFromName={txFromName} value={getIncomingTxAmount(tx)} />
<TransferDescription from={tx.from} txFromName={txFromName} value={getIncomingTxAmount(tx, false)} />
</Block>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ const TxDescription = ({ classes, tx }: Props) => {
removedOwner,
upgradeTx,
} = getTxData(tx)
const amount = getTxAmount(tx)
const amount = getTxAmount(tx, false)
return (
<Block className={classes.txDataContainer}>
{modifySettingsTx && action && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ const ExpandedTx = ({ cancelTx, tx }: Props) => {
const [openModal, setOpenModal] = useState<OpenModal>(null)
const openApproveModal = () => setOpenModal('approveTx')
const closeModal = () => setOpenModal(null)
const thresholdReached = !INCOMING_TX_TYPES.includes(tx.type) && threshold <= tx.confirmations.size
const canExecute = !INCOMING_TX_TYPES.includes(tx.type) && nonce === tx.nonce
const isIncomingTx = !!INCOMING_TX_TYPES[tx.type]
const thresholdReached = !isIncomingTx && threshold <= tx.confirmations.size
const canExecute = !isIncomingTx && nonce === tx.nonce
const cancelThresholdReached = !!cancelTx && threshold <= cancelTx.confirmations.size
const canExecuteCancel = nonce === tx.nonce

Expand All @@ -59,22 +60,22 @@ const ExpandedTx = ({ cancelTx, tx }: Props) => {
<Block className={classes.expandedTxBlock}>
<Row>
<Col layout="column" xs={6}>
<Block
className={cn(classes.txDataContainer, INCOMING_TX_TYPES.includes(tx.type) && classes.incomingTxBlock)}
>
<Block className={cn(classes.txDataContainer, isIncomingTx && classes.incomingTxBlock)}>
<Block align="left" className={classes.txData}>
<Bold className={classes.txHash}>Hash:</Bold>
{tx.executionTxHash ? <EtherScanLink cut={8} type="tx" value={tx.executionTxHash} /> : 'n/a'}
</Block>
<Paragraph noMargin>
<Bold>Nonce: </Bold>
<Span>{tx.nonce}</Span>
</Paragraph>
{!isIncomingTx && (
<Paragraph noMargin>
<Bold>Nonce: </Bold>
<Span>{tx.nonce}</Span>
</Paragraph>
)}
<Paragraph noMargin>
<Bold>Fee: </Bold>
{tx.fee ? tx.fee : 'n/a'}
</Paragraph>
{INCOMING_TX_TYPES.includes(tx.type) ? (
{isIncomingTx ? (
<>
<Paragraph noMargin>
<Bold>Created: </Bold>
Expand Down Expand Up @@ -113,9 +114,9 @@ const ExpandedTx = ({ cancelTx, tx }: Props) => {
)}
</Block>
<Hairline />
{INCOMING_TX_TYPES.includes(tx.type) ? <IncomingTxDescription tx={tx} /> : <TxDescription tx={tx} />}
{isIncomingTx ? <IncomingTxDescription tx={tx} /> : <TxDescription tx={tx} />}
</Col>
{!INCOMING_TX_TYPES.includes(tx.type) && (
{!isIncomingTx && (
<OwnersColumn
cancelThresholdReached={cancelThresholdReached}
cancelTx={cancelTx}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const TxType = ({ origin, txType }: { txType: TransactionType, origin: string |
const parsedOrigin = getAppInfoFromOrigin(origin)
if (!parsedOrigin) {
setForceCustom(true)
setLoading(false)
return
}
const appInfo = await getAppInfoFromUrl(parsedOrigin.url)
Expand All @@ -52,7 +53,7 @@ const TxType = ({ origin, txType }: { txType: TransactionType, origin: string |
}

getAppInfo()
}, [txType])
}, [origin, txType])

if (forceCustom || !origin) {
return <IconText iconUrl={typeToIcon[txType]} text={typeToLabel[txType]} />
Expand Down
52 changes: 31 additions & 21 deletions src/routes/safe/components/Transactions/TxsTable/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import TxType from './TxType'
import { type Column } from '~/components/Table/TableHead'
import { type SortRow, buildOrderFieldFrom } from '~/components/Table/sorting'
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { INCOMING_TX_TYPES, type IncomingTransaction } from '~/routes/safe/store/models/incomingTransaction'
import { type Transaction } from '~/routes/safe/store/models/transaction'

Expand All @@ -34,29 +33,40 @@ type TxData = {

export const formatDate = (date: string): string => format(parseISO(date), 'MMM d, yyyy - HH:mm:ss')

export const getIncomingTxAmount = (tx: IncomingTransaction) => {
const txAmount = tx.value ? `${new BigNumber(tx.value).div(`1e${tx.decimals}`).toFixed()}` : 'n/a'
return `${txAmount} ${tx.symbol || 'n/a'}`
type TxValues = {
value?: string | number,
decimals?: string | number,
symbol?: string,
}

export const getTxAmount = (tx: Transaction) => {
const web3 = getWeb3()
const { fromWei, toBN } = web3.utils

let txAmount = 'n/a'

if (tx.isTokenTransfer && tx.decodedParams) {
const tokenDecimals = tx.decimals.toNumber ? tx.decimals.toNumber() : tx.decimals
txAmount = `${formatAmount(
BigNumber(tx.decodedParams.value)
.div(10 ** tokenDecimals)
.toString(),
)} ${tx.symbol}`
} else if (Number(tx.value) > 0) {
txAmount = `${fromWei(toBN(tx.value), 'ether')} ${tx.symbol}`
const NOT_AVAILABLE = 'n/a'

const getAmountWithSymbol = ({ decimals = 0, symbol = NOT_AVAILABLE, value }: TxValues, formatted = false) => {
const nonFormattedValue = BigNumber(value).times(`1e-${decimals}`).toFixed()
const finalValue = formatted ? formatAmount(nonFormattedValue).toString() : nonFormattedValue
const txAmount = finalValue === 'NaN' ? NOT_AVAILABLE : finalValue

return `${txAmount} ${symbol}`
}

export const getIncomingTxAmount = (tx: IncomingTransaction, formatted: boolean = true) => {
// simple workaround to avoid displaying unexpected values for incoming NFT transfer
if (INCOMING_TX_TYPES[tx.type] === INCOMING_TX_TYPES.ERC721_TRANSFER) {
return `1 ${tx.symbol}`
}

return getAmountWithSymbol(tx, formatted)
}

export const getTxAmount = (tx: Transaction, formatted: boolean = true) => {
const { decimals = 18, decodedParams, isTokenTransfer, symbol } = tx
const { value } = isTokenTransfer && decodedParams && decodedParams.value ? decodedParams : tx

if (!isTokenTransfer && !(Number(value) > 0)) {
return NOT_AVAILABLE
}

return txAmount
return getAmountWithSymbol({ decimals, symbol, value }, formatted)
}

export type TransactionRow = SortRow<TxData>
Expand Down Expand Up @@ -106,7 +116,7 @@ export const getTxTableData = (
const cancelTxsByNonce = cancelTxs.reduce((acc, tx) => acc.set(tx.nonce, tx), Map())

return transactions.map((tx) => {
if (INCOMING_TX_TYPES.includes(tx.type)) {
if (INCOMING_TX_TYPES[tx.type]) {
return getIncomingTxTableData(tx)
}

Expand Down
28 changes: 17 additions & 11 deletions src/routes/safe/store/actions/fetchTransactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ type IncomingTxServiceModel = {

export const buildTransactionFrom = async (
safeAddress: string,
tx: TxServiceModel,
knownTokens,
tx: TxServiceModel,
txTokenCode,
txTokenDecimals,
txTokenSymbol,
txTokenName,
code,
txTokenSymbol,
): Promise<Transaction> => {
const localSafe = await getLocalSafe(safeAddress)

Expand All @@ -108,7 +108,7 @@ export const buildTransactionFrom = async (
const modifySettingsTx = sameAddress(tx.to, safeAddress) && Number(tx.value) === 0 && !!tx.data
const cancellationTx = sameAddress(tx.to, safeAddress) && Number(tx.value) === 0 && !tx.data
const isERC721Token =
(code && code.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH)) ||
(txTokenCode && txTokenCode.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH)) ||
(isTokenTransfer(tx.data, Number(tx.value)) && !knownTokens.get(tx.to) && txTokenDecimals !== null)
let isSendTokenTx = !isERC721Token && isTokenTransfer(tx.data, Number(tx.value))
const isMultiSendTx = isMultisendTransaction(tx.data, Number(tx.value))
Expand All @@ -118,7 +118,7 @@ export const buildTransactionFrom = async (
let refundParams = null
if (tx.gasPrice > 0) {
const refundSymbol = txTokenSymbol || 'ETH'
const decimals = txTokenName || 18
const decimals = txTokenDecimals || 18
const feeString = (tx.gasPrice * (tx.baseGas + tx.safeTxGas)).toString().padStart(decimals, 0)
const whole = feeString.slice(0, feeString.length - decimals) || '0'
const fraction = feeString.slice(feeString.length - decimals)
Expand Down Expand Up @@ -230,8 +230,8 @@ const addMockSafeCreationTx = (safeAddress): Array<TxServiceModel> => [
const batchRequestTxsData = (txs: any[]) => {
const web3Batch = new web3.BatchRequest()

const whenTxsValues = txs.map((tx) => {
const methods = ['decimals', { method: 'getCode', type: 'eth', args: [tx.to] }, 'symbol', 'name']
const txsTokenInfo = txs.map((tx) => {
const methods = [{ method: 'getCode', type: 'eth', args: [tx.to] }, 'decimals', 'name', 'symbol']
return generateBatchRequests({
abi: ERC20Detailed.abi,
address: tx.to,
Expand All @@ -243,7 +243,7 @@ const batchRequestTxsData = (txs: any[]) => {

web3Batch.execute()

return Promise.all(whenTxsValues)
return Promise.all(txsTokenInfo)
}

const batchRequestIncomingTxsData = (txs: IncomingTxServiceModel[]) => {
Expand Down Expand Up @@ -341,9 +341,15 @@ export const loadSafeTransactions = async (safeAddress: string, getState: GetSta
const txsWithData = await batchRequestTxsData(transactions)
// In case that the etags don't match, we parse the new transactions and save them to the cache
const txsRecord: Array<RecordInstance<TransactionProps>> = await Promise.all(
txsWithData.map(([tx: TxServiceModel, decimals, code, symbol, name]) =>
buildTransactionFrom(safeAddress, tx, knownTokens, decimals, symbol, name, code),
),
txsWithData.map(([tx: TxServiceModel, code, decimals, name, symbol]) => {
const knownToken = knownTokens.get(tx.to)

if (knownToken) {
;({ decimals, name, symbol } = knownToken)
}

return buildTransactionFrom(safeAddress, knownTokens, tx, code, decimals, name, symbol)
}),
)

const groupedTxs = List(txsRecord).groupBy((tx) => (tx.get('cancellationTx') ? 'cancel' : 'outgoing'))
Expand Down
Loading