sats/mo -> sats/min on jobs
This commit is contained in:
parent
cc81db11fb
commit
1472de0f91
@ -517,10 +517,6 @@ export default {
|
|||||||
throw new UserInputError(`bid must be at least ${fullSub.baseCost}`, { argumentName: 'maxBid' })
|
throw new UserInputError(`bid must be at least ${fullSub.baseCost}`, { argumentName: 'maxBid' })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxBid % fullSub.deltaCost !== 0) {
|
|
||||||
throw new UserInputError(`bid must be a multiple of ${fullSub.deltaCost}`, { argumentName: 'maxBid' })
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkSats = async () => {
|
const checkSats = async () => {
|
||||||
// check if the user has the funds to run for the first minute
|
// check if the user has the funds to run for the first minute
|
||||||
const minuteMsats = maxBid * 5 / 216
|
const minuteMsats = maxBid * 5 / 216
|
||||||
|
@ -12,6 +12,5 @@ export default gql`
|
|||||||
postTypes: [String!]!
|
postTypes: [String!]!
|
||||||
rankingType: String!
|
rankingType: String!
|
||||||
baseCost: Int!
|
baseCost: Int!
|
||||||
deltaCost: Int!
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -9,6 +9,7 @@ import styles from '../styles/post.module.css'
|
|||||||
import { useLazyQuery, gql, useMutation } from '@apollo/client'
|
import { useLazyQuery, gql, useMutation } from '@apollo/client'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { usePrice } from './price'
|
||||||
|
|
||||||
Yup.addMethod(Yup.string, 'or', function (schemas, msg) {
|
Yup.addMethod(Yup.string, 'or', function (schemas, msg) {
|
||||||
return this.test({
|
return this.test({
|
||||||
@ -26,15 +27,26 @@ Yup.addMethod(Yup.string, 'or', function (schemas, msg) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function satsMo2Min (monthly) {
|
function satsMin2Mo (minute) {
|
||||||
return Number.parseFloat(monthly / 30 / 24 / 60).toFixed(2)
|
return minute * 30 * 24 * 60
|
||||||
|
}
|
||||||
|
|
||||||
|
function PriceHint ({ monthly }) {
|
||||||
|
const price = usePrice()
|
||||||
|
if (!price) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const fixed = (n, f) => Number.parseFloat(n).toFixed(f)
|
||||||
|
const fiat = fixed((price / 100000000) * monthly, 0)
|
||||||
|
|
||||||
|
return <span className='text-muted'>{monthly} sats/mo which is ${fiat}/mo</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to recent list items
|
// need to recent list items
|
||||||
export default function JobForm ({ item, sub }) {
|
export default function JobForm ({ item, sub }) {
|
||||||
const storageKeyPrefix = item ? undefined : `${sub.name}-job`
|
const storageKeyPrefix = item ? undefined : `${sub.name}-job`
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [pull, setPull] = useState(satsMo2Min(item?.maxBid || sub.baseCost))
|
const [monthly, setMonthly] = useState(satsMin2Mo(item?.maxBid || sub.baseCost))
|
||||||
const [info, setInfo] = useState()
|
const [info, setInfo] = useState()
|
||||||
const [getAuctionPosition, { data }] = useLazyQuery(gql`
|
const [getAuctionPosition, { data }] = useLazyQuery(gql`
|
||||||
query AuctionPosition($id: ID, $bid: Int!) {
|
query AuctionPosition($id: ID, $bid: Int!) {
|
||||||
@ -59,8 +71,6 @@ export default function JobForm ({ item, sub }) {
|
|||||||
.required('Required'),
|
.required('Required'),
|
||||||
maxBid: Yup.number('must be number')
|
maxBid: Yup.number('must be number')
|
||||||
.integer('must be integer').min(sub.baseCost, `must be at least ${sub.baseCost}`)
|
.integer('must be integer').min(sub.baseCost, `must be at least ${sub.baseCost}`)
|
||||||
.max(100000000, 'must be less than 100000000')
|
|
||||||
.test('multiple', `must be a multiple of ${sub.deltaCost} sats`, (val) => val % sub.deltaCost === 0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const position = data?.auctionPosition
|
const position = data?.auctionPosition
|
||||||
@ -68,7 +78,7 @@ export default function JobForm ({ item, sub }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initialMaxBid = Number(item?.maxBid || localStorage.getItem(storageKeyPrefix + '-maxBid')) || sub.baseCost
|
const initialMaxBid = Number(item?.maxBid || localStorage.getItem(storageKeyPrefix + '-maxBid')) || sub.baseCost
|
||||||
getAuctionPosition({ variables: { id: item?.id, bid: initialMaxBid } })
|
getAuctionPosition({ variables: { id: item?.id, bid: initialMaxBid } })
|
||||||
setPull(satsMo2Min(initialMaxBid))
|
setMonthly(satsMin2Mo(initialMaxBid))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -81,8 +91,7 @@ export default function JobForm ({ item, sub }) {
|
|||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<ol className='font-weight-bold'>
|
<ol className='font-weight-bold'>
|
||||||
<li>The higher your bid the higher your job will rank</li>
|
<li>The higher your bid the higher your job will rank</li>
|
||||||
<li>The minimum bid is {sub.baseCost} sats/mo</li>
|
<li>The minimum bid is {sub.baseCost} sats/min</li>
|
||||||
<li>Your sats/mo must be a multiple of {sub.deltaCost} sats</li>
|
|
||||||
<li>You can increase or decrease your bid, and edit or stop your job at anytime</li>
|
<li>You can increase or decrease your bid, and edit or stop your job at anytime</li>
|
||||||
<li>Your job will be hidden if your wallet runs out of sats and can be unhidden by filling your wallet again</li>
|
<li>Your job will be hidden if your wallet runs out of sats and can be unhidden by filling your wallet again</li>
|
||||||
</ol>
|
</ol>
|
||||||
@ -151,14 +160,14 @@ export default function JobForm ({ item, sub }) {
|
|||||||
name='maxBid'
|
name='maxBid'
|
||||||
onChange={async (formik, e) => {
|
onChange={async (formik, e) => {
|
||||||
if (e.target.value >= sub.baseCost && e.target.value <= 100000000) {
|
if (e.target.value >= sub.baseCost && e.target.value <= 100000000) {
|
||||||
setPull(satsMo2Min(e.target.value))
|
setMonthly(satsMin2Mo(e.target.value))
|
||||||
getAuctionPosition({ variables: { id: item?.id, bid: Number(e.target.value) } })
|
getAuctionPosition({ variables: { id: item?.id, bid: Number(e.target.value) } })
|
||||||
} else {
|
} else {
|
||||||
setPull(satsMo2Min(sub.baseCost))
|
setMonthly(satsMin2Mo(sub.baseCost))
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
append={<InputGroup.Text className='text-monospace'>sats/month</InputGroup.Text>}
|
append={<InputGroup.Text className='text-monospace'>sats/min</InputGroup.Text>}
|
||||||
hint={<span className='text-muted'>{pull} sats/min will be pulled from your wallet</span>}
|
hint={<PriceHint monthly={monthly} />}
|
||||||
/>
|
/>
|
||||||
<><div className='font-weight-bold text-muted'>This bid puts your job in position: {position}</div></>
|
<><div className='font-weight-bold text-muted'>This bid puts your job in position: {position}</div></>
|
||||||
{item && <StatusControl item={item} />}
|
{item && <StatusControl item={item} />}
|
||||||
|
@ -21,7 +21,6 @@ export const ITEM_FIELDS = gql`
|
|||||||
sub {
|
sub {
|
||||||
name
|
name
|
||||||
baseCost
|
baseCost
|
||||||
deltaCost
|
|
||||||
}
|
}
|
||||||
status
|
status
|
||||||
mine
|
mine
|
||||||
|
@ -7,7 +7,6 @@ export const SUB_FIELDS = gql`
|
|||||||
postTypes
|
postTypes
|
||||||
rankingType
|
rankingType
|
||||||
baseCost
|
baseCost
|
||||||
deltaCost
|
|
||||||
}`
|
}`
|
||||||
|
|
||||||
export const SUB = gql`
|
export const SUB = gql`
|
||||||
|
39
prisma/migrations/20220307181836_sats_min/migration.sql
Normal file
39
prisma/migrations/20220307181836_sats_min/migration.sql
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Sub" DROP COLUMN "deltaCost";
|
||||||
|
|
||||||
|
-- charge the user for the auction item
|
||||||
|
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER) RETURNS void AS $$
|
||||||
|
DECLARE
|
||||||
|
bid INTEGER;
|
||||||
|
user_id INTEGER;
|
||||||
|
user_msats INTEGER;
|
||||||
|
item_status "Status";
|
||||||
|
BEGIN
|
||||||
|
PERFORM ASSERT_SERIALIZED();
|
||||||
|
|
||||||
|
-- extract data we need
|
||||||
|
SELECT "maxBid" * 1000, "userId", status INTO bid, user_id, item_status FROM "Item" WHERE id = item_id;
|
||||||
|
SELECT msats INTO user_msats FROM users WHERE id = user_id;
|
||||||
|
|
||||||
|
-- check if user wallet has enough sats
|
||||||
|
IF bid > user_msats THEN
|
||||||
|
-- if not, set status = NOSATS and statusUpdatedAt to now_utc if not already set
|
||||||
|
IF item_status <> 'NOSATS' THEN
|
||||||
|
UPDATE "Item" SET status = 'NOSATS', "statusUpdatedAt" = now_utc() WHERE id = item_id;
|
||||||
|
END IF;
|
||||||
|
ELSE
|
||||||
|
-- if so, deduct from user
|
||||||
|
UPDATE users SET msats = msats - bid WHERE id = user_id;
|
||||||
|
-- update item status = ACTIVE and statusUpdatedAt = null if NOSATS
|
||||||
|
IF item_status = 'NOSATS' THEN
|
||||||
|
UPDATE "Item" SET status = 'ACTIVE', "statusUpdatedAt" = now_utc() WHERE id = item_id;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
-- update all existing subs baseCost to 12
|
||||||
|
update "Sub" set "baseCost" = 12 where name = 'jobs';
|
||||||
|
|
||||||
|
-- modify items with a maxBid to sats/min
|
||||||
|
update "Item" set "maxBid" = GREATEST("maxBid" / 30 / 24 / 60, 1) where "maxBid" is not null;
|
@ -145,7 +145,6 @@ model Sub {
|
|||||||
postTypes PostType[]
|
postTypes PostType[]
|
||||||
rankingType RankingType
|
rankingType RankingType
|
||||||
baseCost Int @default(1)
|
baseCost Int @default(1)
|
||||||
deltaCost Int @default(0)
|
|
||||||
desc String?
|
desc String?
|
||||||
|
|
||||||
Item Item[]
|
Item Item[]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user