src/modules/notifications/actions/set-notification-text.js
/**
* @todo Update text for FINALIZE once notification triggering is moved
*/
import { augur } from "services/augurjs";
import { isEmpty } from "lodash/fp";
import { selectMarket } from "modules/markets/selectors/market";
import { loadMarketsInfoIfNotLoaded } from "modules/markets/actions/load-markets-info";
import { TEN_TO_THE_EIGHTEENTH_POWER } from "modules/trades/constants/numbers";
import { getOutcome } from "modules/transactions/actions/add-transactions";
import { BUY, SELL } from "modules/trades/constants/types";
import { formatEther, formatRep, formatShares } from "utils/format-number";
import calculatePayoutNumeratorsValue from "utils/calculate-payout-numerators-value";
import { createBigNumber } from "utils/create-big-number";
import {
CREATEGENESISUNIVERSE,
CANCELORPHANEDORDER,
CANCELORDER,
WITHDRAWETHERTOIFPOSSIBLE,
CALCULATEREPORTINGFEE,
CLAIMTRADINGPROCEEDS,
PUBLICBUYCOMPLETESETS,
PUBLICBUYCOMPLETESETSWITHCASH,
PUBLICSELLCOMPLETESETS,
PUBLICSELLCOMPLETESETSWITHCASH,
PUBLICCREATEORDER,
BUYPARTICIPATIONTOKENS,
PUBLICFILLBESTORDER,
PUBLICFILLBESTORDERWITHLIMIT,
PUBLICFILLORDER,
MIGRATEREP,
WITHDRAWETHER,
WITHDRAWTOKENS,
CONTRIBUTE,
DISAVOWCROWDSOURCERS,
DOINITIALREPORT,
FINALIZE,
FINALIZEFORK,
MIGRATETHROUGHONEFORK,
MIGRATEBALANCESFROMLEGACYREP,
MIGRATEALLOWANCESFROMLEGACYREP,
MIGRATEIN,
MIGRATEOUT,
MIGRATEOUTBYPAYOUT,
UPDATEPARENTTOTALTHEORETICALSUPPLY,
UPDATESIBLINGMIGRATIONTOTAL,
PUBLICBUY,
PUBLICBUYWITHLIMIT,
PUBLICSELL,
PUBLICSELLWITHLIMIT,
PUBLICTRADE,
PUBLICTRADEWITHLIMIT,
FAUCET,
CLAIMSHARESINUPDATE,
GETFROZENSHAREVALUEINMARKET,
CREATEMARKET,
CREATECATEGORICALMARKET,
CREATESCALARMARKET,
CREATEYESNOMARKET,
CREATECHILDUNIVERSE,
FORK,
REDEEMSTAKE,
GETINITIALREPORTSTAKESIZE,
GETORCACHEDESIGNATEDREPORTNOSHOWBOND,
GETORCACHEDESIGNATEDREPORTSTAKE,
GETORCACHEMARKETCREATIONCOST,
GETORCACHEREPORTINGFEEDIVISOR,
GETORCACHEVALIDITYBOND,
GETORCREATECURRENTFEEWINDOW,
GETORCREATEFEEWINDOWBYTIMESTAMP,
GETORCREATENEXTFEEWINDOW,
GETORCREATEPREVIOUSFEEWINDOW,
UPDATEFORKVALUES,
APPROVE,
DECREASEAPPROVAL,
DEPOSITETHER,
DEPOSITETHERFOR,
FORKANDREDEEM,
REDEEMFORREPORTINGPARTICIPANT,
REDEEM,
INCREASEAPPROVAL,
MIGRATE,
TRANSFER,
TRANSFERFROM,
TRANSFEROWNERSHIP,
WITHDRAWETHERTO,
WITHDRAWINEMERGENCY,
SENDETHER,
SENDREPUTATION
} from "modules/notifications/constants/notifications";
export default function setNotificationText(notification, callback) {
return (dispatch, getState) => {
if (!notification || isEmpty(notification)) {
return dispatch(callback(notification));
}
if (!callback) {
throw new Error("Callback function is not set");
}
if (
!notification.params ||
(notification.title && notification.description)
) {
return dispatch(callback(notification));
}
switch (notification.params.type.toUpperCase()) {
// Augur
case CREATEGENESISUNIVERSE:
notification.title = "Create genesis universe";
break;
// CancelOrder
case CANCELORPHANEDORDER:
notification.title = "Cancel orphaned order";
if (!notification.description && notification.log) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.log.marketId], () => {
const marketInfo = selectMarket(notification.log.marketId);
const outcomeDescription = getOutcome(
marketInfo,
notification.log.outcome
);
notification.description = `Cancel orphaned order for ${formatShares(
notification.log.quantity
).denomination.toLowerCase()} of "${outcomeDescription}" at ${
formatEther(notification.log.price).formatted
} ETH`;
return dispatch(callback(notification));
})
);
}
break;
case CANCELORDER: {
notification.title = "Cancel order";
if (!notification.description && notification.log) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.log.marketId], () => {
const marketInfo = selectMarket(notification.log.marketId);
const outcomeDescription = getOutcome(
marketInfo,
notification.log.outcome
);
notification.description = `Cancel order for ${formatShares(
notification.log.quantity
).denomination.toLowerCase()} of "${outcomeDescription}" at ${
formatEther(notification.log.price).formatted
} ETH`;
return dispatch(callback(notification));
})
);
}
break;
}
// Cash
case WITHDRAWETHERTOIFPOSSIBLE:
notification.title = "Withdraw ETH";
break;
// ClaimTradingProceeds
case CALCULATEREPORTINGFEE:
notification.title = "Calculate reporting fee";
break;
case CLAIMTRADINGPROCEEDS:
notification.title = "Claim trading proceeds";
break;
// CompleteSets
case PUBLICBUYCOMPLETESETS:
case PUBLICBUYCOMPLETESETSWITHCASH:
notification.title = "Buy complete set(s)";
break;
case PUBLICSELLCOMPLETESETS:
case PUBLICSELLCOMPLETESETSWITHCASH:
notification.title = "Sell complete set(s)";
break;
// CreateOrder
case PUBLICCREATEORDER: {
notification.title = "Create order";
if (!notification.description && notification.log) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.params._market], () => {
const marketInfo = selectMarket(notification.params._market);
const outcomeDescription = getOutcome(
marketInfo,
notification.log.outcome
);
notification.description = `Create ${
notification.log.orderType
} order for ${formatShares(notification.log.amount).formatted} ${
formatShares(notification.log.amount).denomination
} of "${outcomeDescription}" at ${
formatEther(notification.log.price).formatted
} ETH`;
return dispatch(callback(notification));
})
);
}
break;
}
// FeeWindow & Universe
case "BUY":
case BUYPARTICIPATIONTOKENS:
notification.title = "Buy participation token(s)";
if (!notification.description && notification.log) {
notification.description = `Purchase ${
formatRep(
createBigNumber(notification.log.value).dividedBy(
TEN_TO_THE_EIGHTEENTH_POWER
)
).formatted
} Participation Token${
notification.log.value === TEN_TO_THE_EIGHTEENTH_POWER ? "" : "s"
}`;
}
break;
// FillOrder & Trade
case PUBLICFILLBESTORDER:
case PUBLICFILLBESTORDERWITHLIMIT:
case PUBLICFILLORDER:
notification.title = "Place trade";
if (!notification.description && notification.log) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.params._market], () => {
const marketInfo = selectMarket(notification.params._market);
const outcomeDescription = getOutcome(
marketInfo,
marketInfo.outcomes.find(
outcome =>
outcome.id ===
createBigNumber(notification.params._outcome).toFixed()
).name
);
notification.description = `Fill ${
notification.log.orderType === BUY ? "selling" : "buying"
} ${formatShares(notification.log.amount || 0).formatted} ${
formatShares(notification.log.amount || 0).denomination
} of "${outcomeDescription}" at ${
formatEther(notification.log.price).formatted
} ETH`;
if (notification.log.noFill) {
notification.description = `Unable to ${
notification.log.orderType === BUY ? "sell" : "buy"
} ${notification.log.difference || ""} ${
formatShares(notification.log.difference || 10).denomination
} of "${outcomeDescription}" at ${augur.utils.convertOnChainPriceToDisplayPrice(
createBigNumber(notification.params._price),
createBigNumber(marketInfo.minPrice),
marketInfo.tickSize
)} ETH.`;
}
return dispatch(callback(notification));
})
);
}
break;
// InitialReporter
case MIGRATEREP:
notification.title = "Migrate REP";
break;
// Mailbox
case WITHDRAWETHER:
notification.title = "Withdraw ETH";
break;
case WITHDRAWTOKENS:
notification.title = "Withdraw tokens";
break;
// Market
case CONTRIBUTE:
notification.title = "Contribute to Dispute Bond";
if (!notification.description) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.to], () => {
const marketInfo = selectMarket(notification.to);
const outcome = calculatePayoutNumeratorsValue(
marketInfo,
notification.params._payoutNumerators,
notification.params._invalid
);
const outcomeDescription =
outcome === null
? "Market Is Invalid"
: getOutcome(marketInfo, outcome, false);
notification.description = `Place ${
formatRep(
createBigNumber(notification.params._amount).dividedBy(
TEN_TO_THE_EIGHTEENTH_POWER
)
).formatted
} REP on "${outcomeDescription}"`;
return dispatch(callback(notification));
})
);
}
break;
case DISAVOWCROWDSOURCERS:
notification.title = "Make staked REP available for claiming";
break;
case DOINITIALREPORT:
notification.title = "Submit report";
if (!notification.description) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.to], () => {
const marketInfo = selectMarket(notification.to);
const outcome = calculatePayoutNumeratorsValue(
marketInfo,
notification.params._payoutNumerators,
notification.params._invalid
);
const outcomeDescription =
outcome === null
? "Market Is Invalid"
: getOutcome(marketInfo, outcome, false);
notification.description = `Report "${outcomeDescription}" on "${
marketInfo.description
}"`;
return dispatch(callback(notification));
})
);
}
break;
case FINALIZE:
// Market finalization notifications should only be displayed if
// the market creator is the same as the account that's logged in
notification.title = "Finalize market";
if (!notification.description && notification.log) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.log.market], () => {
const marketDescription = selectMarket(notification.log.market)
.description;
notification.description =
'Finalize market "' + marketDescription + '"';
return dispatch(callback(notification));
})
);
}
break;
case FINALIZEFORK:
notification.title = "Finalize forked market";
break;
case MIGRATETHROUGHONEFORK:
notification.title = "Migrate market to winning child universe";
break;
// ReputationToken
case MIGRATEBALANCESFROMLEGACYREP:
notification.title = "Migrate balances from legacy REP contract";
break;
case MIGRATEALLOWANCESFROMLEGACYREP:
notification.title = "Migrate allowances from legacy REP contract";
break;
case MIGRATEIN:
notification.title = "Migrate REP into universe";
break;
case MIGRATEOUT:
notification.title = "Migrate REP out of universe";
break;
case MIGRATEOUTBYPAYOUT:
notification.title = "Migrate REP out of universe";
if (!notification.description && notification.log) {
const forkingMarketId = getState().universe.forkingMarket;
dispatch(
loadMarketsInfoIfNotLoaded([forkingMarketId], () => {
const marketInfo = selectMarket(forkingMarketId);
const outcome = calculatePayoutNumeratorsValue(
marketInfo,
notification.params._payoutNumerators,
notification.params._invalid
);
const outcomeDescription = getOutcome(marketInfo, outcome, false);
notification.description = `Migrate ${
formatRep(
createBigNumber(notification.log.value).dividedBy(
TEN_TO_THE_EIGHTEENTH_POWER
)
).formatted
} REP to child universe "${outcomeDescription}"`;
return dispatch(callback(notification));
})
);
}
break;
case UPDATEPARENTTOTALTHEORETICALSUPPLY:
notification.title =
"Update theoretical REP supply for parent universe";
break;
case UPDATESIBLINGMIGRATIONTOTAL:
notification.title =
"Update theoretical REP supply for sibling universe";
break;
// Trade
case PUBLICBUY:
case PUBLICBUYWITHLIMIT:
notification.title = "Buy share(s)";
break;
case PUBLICSELL:
case PUBLICSELLWITHLIMIT:
notification.title = "Sell share(s)";
break;
case PUBLICTRADE:
case PUBLICTRADEWITHLIMIT: {
notification.title = "Place trade";
if (!notification.description && notification.log) {
dispatch(
loadMarketsInfoIfNotLoaded([notification.params._market], () => {
const marketInfo = selectMarket(notification.params._market);
const orderType =
notification.params._direction === "0x0" ? BUY : SELL;
const outcomeDescription = getOutcome(
marketInfo,
notification.log.outcome
);
notification.description = `Place ${orderType} order for ${
formatShares(notification.amount || notification.log.amount)
.formatted
} ${formatShares(
notification.log.amount
).denomination.toLowerCase()} of "${outcomeDescription}" at ${
formatEther(notification.log.price).formatted
} ETH`;
return dispatch(callback(notification));
})
);
}
break;
}
// TestNetReputationToken
case FAUCET:
notification.title = "Get REP from faucet";
break;
// TradingEscapeHatch
case CLAIMSHARESINUPDATE:
notification.title = "Claim share(s) from market";
break;
case GETFROZENSHAREVALUEINMARKET:
notification.title = "Liquidate share(s) in market to ETH";
break;
// Universe
case CREATEMARKET:
case CREATECATEGORICALMARKET:
case CREATESCALARMARKET:
case CREATEYESNOMARKET:
notification.title = "Create new market";
if (!notification.description) {
notification.description = `Create market "${
notification.params._description
}"`;
}
break;
case CREATECHILDUNIVERSE:
notification.title = "Create child universe";
break;
case FORK:
notification.title = "Initiate fork";
break;
case REDEEMSTAKE:
notification.title = "Claim staked REP/Ether";
break;
case GETINITIALREPORTSTAKESIZE:
notification.title = "Get initial report stake size";
break;
case GETORCACHEDESIGNATEDREPORTNOSHOWBOND:
notification.title = "Get no-show bond size for markets";
break;
case GETORCACHEDESIGNATEDREPORTSTAKE:
notification.title = "Get stake size required for desginated reports";
break;
case GETORCACHEMARKETCREATIONCOST:
notification.title = "Get market creation cost";
break;
case GETORCACHEREPORTINGFEEDIVISOR:
notification.title = "Get reporting fee divisor";
break;
case GETORCACHEVALIDITYBOND:
notification.title =
"Get validity bond size required for market creation";
break;
case GETORCREATECURRENTFEEWINDOW:
notification.title = "Get/create current fee window address";
break;
case GETORCREATEFEEWINDOWBYTIMESTAMP:
notification.title = "Get/create fee window by timestamp";
break;
case GETORCREATENEXTFEEWINDOW:
notification.title = "Get/create next fee window";
break;
case GETORCREATEPREVIOUSFEEWINDOW:
notification.title = "Get/create previous fee window";
break;
case UPDATEFORKVALUES:
notification.title = "Update fork values";
break;
// These transaction names are overloaded across multiple contracts
case APPROVE:
notification.title = "Approve spending";
break;
case DECREASEAPPROVAL:
notification.title = "Decrease spending approval";
break;
case DEPOSITETHER:
case DEPOSITETHERFOR:
notification.title = "Deposit ETH";
break;
case FORKANDREDEEM:
case REDEEMFORREPORTINGPARTICIPANT:
notification.title = "Redeem funds";
break;
case REDEEM:
notification.title = "Redeem funds";
if (!notification.description && notification.log) {
notification.description = `Claim ${
formatRep(
createBigNumber(notification.log.value).dividedBy(
TEN_TO_THE_EIGHTEENTH_POWER
)
).formatted
} REP`;
}
break;
case INCREASEAPPROVAL:
notification.title = "Increase spending approval";
break;
case MIGRATE:
notification.title = "Migrate funds";
break;
case TRANSFER:
case TRANSFERFROM:
case TRANSFEROWNERSHIP:
// Ignore this case for now, since it seems redundant with some other notifications
break;
case WITHDRAWETHERTO:
notification.title = "Withdraw ETH";
break;
case WITHDRAWINEMERGENCY:
notification.title = "Withdraw funds";
break;
// augur.js functions
case SENDETHER:
notification.title = "Send ETH";
if (!notification.description && notification.params) {
notification.description = `Send ${
formatEther(notification.params.etherToSend).formatted
} ETH to ${notification.params.to}`;
}
break;
case SENDREPUTATION:
notification.title = "Send REP";
if (!notification.description && notification.params) {
notification.description = `Send ${
formatRep(notification.params.reputationToSend).formatted
} REP to ${notification.params._to}`;
}
break;
default: {
const result = notification.params.type
.replace(/([A-Z])/g, " $1")
.toLowerCase();
notification.title = result;
break;
}
}
dispatch(callback(notification));
};
}