Allow unspecfied outcome as input to sellshares

This commit is contained in:
Marshall Polaris 2022-07-31 23:38:45 -07:00
parent ae2e7dfe30
commit ff9a649c3c
2 changed files with 27 additions and 8 deletions

View File

@ -581,12 +581,12 @@ $ curl https://manifold.markets/api/v0/market/{marketId}/resolve -X POST \
### `POST /v0/market/[marketId]/sell` ### `POST /v0/market/[marketId]/sell`
Sells some quantity of shares in a market on behalf of the authorized user. Sells some quantity of shares in a binary market on behalf of the authorized user.
Parameters: Parameters:
- `outcome`: Required. One of `YES`, `NO`, or a `number` indicating the numeric - `outcome`: Optional. One of `YES`, or `NO`. If you leave it off, and you only
bucket ID, depending on the market type. own one kind of shares, you will sell that kind of shares.
- `shares`: Optional. The amount of shares to sell of the outcome given - `shares`: Optional. The amount of shares to sell of the outcome given
above. If not provided, all the shares you own will be sold. above. If not provided, all the shares you own will be sold.

View File

@ -1,4 +1,4 @@
import { sumBy, uniq } from 'lodash' import { mapValues, groupBy, sumBy, uniq } from 'lodash'
import * as admin from 'firebase-admin' import * as admin from 'firebase-admin'
import { z } from 'zod' import { z } from 'zod'
@ -17,7 +17,7 @@ import { redeemShares } from './redeem-shares'
const bodySchema = z.object({ const bodySchema = z.object({
contractId: z.string(), contractId: z.string(),
shares: z.number().optional(), // leave it out to sell all shares shares: z.number().optional(), // leave it out to sell all shares
outcome: z.enum(['YES', 'NO']), outcome: z.enum(['YES', 'NO']).optional(), // leave it out to sell whichever you have
}) })
export const sellshares = newEndpoint({}, async (req, auth) => { export const sellshares = newEndpoint({}, async (req, auth) => {
@ -46,9 +46,28 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
throw new APIError(400, 'Trading is closed.') throw new APIError(400, 'Trading is closed.')
const prevLoanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0) const prevLoanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0)
const betsByOutcome = groupBy(userBets, (bet) => bet.outcome)
const sharesByOutcome = mapValues(betsByOutcome, (bets) =>
sumBy(bets, (b) => b.shares)
)
const outcomeBets = userBets.filter((bet) => bet.outcome == outcome) let chosenOutcome: 'YES' | 'NO'
const maxShares = sumBy(outcomeBets, (bet) => bet.shares) if (outcome != null) {
chosenOutcome = outcome
} else {
const nonzeroShares = Object.entries(sharesByOutcome).filter(
([_k, v]) => v
)
if (nonzeroShares.length > 1) {
throw new APIError(
400,
`You own multiple kinds of shares, but did not specify which to sell.`
)
}
chosenOutcome = nonzeroShares[0][0] as 'YES' | 'NO'
}
const maxShares = sharesByOutcome[chosenOutcome]
const sharesToSell = shares ?? maxShares const sharesToSell = shares ?? maxShares
if (!floatingLesserEqual(sharesToSell, maxShares)) if (!floatingLesserEqual(sharesToSell, maxShares))
@ -63,7 +82,7 @@ export const sellshares = newEndpoint({}, async (req, auth) => {
const { newBet, newPool, newP, fees, makers } = getCpmmSellBetInfo( const { newBet, newPool, newP, fees, makers } = getCpmmSellBetInfo(
soldShares, soldShares,
outcome, chosenOutcome,
contract, contract,
prevLoanAmount, prevLoanAmount,
unfilledBets unfilledBets