Compare commits

...

5 Commits

Author SHA1 Message Date
Keyan 8000886e72
dont expect unrun services in dev (#1279) 2024-07-31 19:44:08 -05:00
keyan 4b391dd6ee add separators to all unabbreviated numbers 2024-07-31 19:02:33 -05:00
Keyan e6f6895ce0
Update awards.csv 2024-07-31 12:22:30 -05:00
Keyan 837767a323
Update awards.csv 2024-07-31 12:18:26 -05:00
keyan 7901f2fe61 fix anon zaps (no tip settings) 2024-07-30 18:09:46 -05:00
11 changed files with 58 additions and 39 deletions

View File

@ -1,6 +1,7 @@
PRISMA_SLOW_LOGS_MS= PRISMA_SLOW_LOGS_MS=
GRAPHQL_SLOW_LOGS_MS= GRAPHQL_SLOW_LOGS_MS=
NODE_ENV=development NODE_ENV=development
COMPOSE_PROFILES='minimal,images,search,payments,wallets,email,capture'
############################################################################ ############################################################################
# OPTIONAL SECRETS # # OPTIONAL SECRETS #
@ -114,8 +115,6 @@ POSTGRES_DB=stackernews
# opensearch container stuff # opensearch container stuff
OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh
plugins.security.disabled=true
discovery.type=single-node
DISABLE_SECURITY_DASHBOARDS_PLUGIN=true DISABLE_SECURITY_DASHBOARDS_PLUGIN=true
# bitcoind container stuff # bitcoind container stuff

View File

@ -76,6 +76,7 @@ COMMANDS
sn: sn:
login login as a nym login login as a nym
fund_user fund a nym without using an LN invoice
lnd: lnd:
fund pay a bolt11 for funding fund pay a bolt11 for funding
@ -92,12 +93,14 @@ COMMANDS
dev: dev:
pr fetch and checkout a pr pr fetch and checkout a pr
lint run linters lint run linters
open open container url in browser
other: other:
compose docker compose passthrough compose docker compose passthrough
sn_lndcli lncli passthrough on sn_lnd sn_lndcli lncli passthrough on sn_lnd
stacker_lndcli lncli passthrough on stacker_lnd stacker_lndcli lncli passthrough on stacker_lnd
stacker_clncli lightning-cli passthrough on stacker_cln stacker_clncli lightning-cli passthrough on stacker_cln
stacker_litcli litcli passthrough on litd
``` ```
@ -105,23 +108,16 @@ COMMANDS
#### Running specific services #### Running specific services
By default all services will be run. If you want to exclude specific services from running, set `COMPOSE_PROFILES` to use one or more of `minimal|images|search|payments|wallets|email|capture`. To only run mininal services without images, search, email, wallets, or payments: By default all services will be run. If you want to exclude specific services from running, set `COMPOSE_PROFILES` in a `.env.local` file to one or more of `minimal,images,search,payments,wallets,email,capture`. To only run mininal necessary without things like payments in `.env.local`:
```sh ```.env
$ COMPOSE_PROFILES=minimal ./sndev start COMPOSE_PROFILES=minimal
```
Or, as I would recommend:
```sh
$ export COMPOSE_PROFILES=minimal
$ ./sndev start
``` ```
To run with images and payments services: To run with images and payments services:
```sh ```.env
$ COMPOSE_PROFILES=images,payments ./sndev start COMPOSE_PROFILES=images,payments
``` ```
#### Merging compose files #### Merging compose files
@ -460,7 +456,9 @@ In addition, we run other critical services the above services interact with lik
## Wallet transaction safety ## Wallet transaction safety
To ensure stackers balances are kept sane, all wallet updates are run in [serializable transactions](https://www.postgresql.org/docs/current/transaction-iso.html#XACT-SERIALIZABLE) at the database level. Because early versions of prisma had relatively poor support for transactions most wallet touching code is written in [plpgsql](https://www.postgresql.org/docs/current/plpgsql.html) stored procedures and can be found in the `prisma/migrations` folder. To ensure stackers balances are kept sane, some wallet updates are run in [serializable transactions](https://www.postgresql.org/docs/current/transaction-iso.html#XACT-SERIALIZABLE) at the database level. Because early versions of prisma had relatively poor support for transactions most wallet touching code is written in [plpgsql](https://www.postgresql.org/docs/current/plpgsql.html) stored procedures and can be found in the `prisma/migrations` folder.
*UPDATE*: Most wallet updates are now run in [read committed](https://www.postgresql.org/docs/current/transaction-iso.html#XACT-READ-COMMITTED) transactions. See `api/paidAction/README.md` for more information.
<br> <br>

View File

@ -1,11 +1,13 @@
import lndService from 'ln-service' import lndService from 'ln-service'
import lnd from '@/api/lnd' import lnd from '@/api/lnd'
import { isServiceEnabled } from '@/lib/sndev'
const cache = new Map() const cache = new Map()
const expiresIn = 1000 * 30 // 30 seconds in milliseconds const expiresIn = 1000 * 30 // 30 seconds in milliseconds
async function fetchBlockHeight () { async function fetchBlockHeight () {
let blockHeight = 0 let blockHeight = 0
if (!isServiceEnabled('payments')) return blockHeight
try { try {
const height = await lndService.getHeight({ lnd }) const height = await lndService.getHeight({ lnd })
blockHeight = height.current_block_height blockHeight = height.current_block_height

View File

@ -115,3 +115,7 @@ cointastical,issue,#1223,#107,medium,,2,,20k,cointastical@stacker.news,2024-06-2
kravhen,pr,#1215,#253,medium,,2,upgraded to medium,200k,nichro@getalby.com,2024-06-28 kravhen,pr,#1215,#253,medium,,2,upgraded to medium,200k,nichro@getalby.com,2024-06-28
dillon-co,pr,#1140,#633,hard,,,requested advance,500k,bolt11,2024-07-02 dillon-co,pr,#1140,#633,hard,,,requested advance,500k,bolt11,2024-07-02
takitakitanana,issue,,#1257,good-first-issue,,,,2k,takitakitanana@stacker.news,2024-07-11 takitakitanana,issue,,#1257,good-first-issue,,,,2k,takitakitanana@stacker.news,2024-07-11
SatsAllDay,pr,#1263,#1112,medium,,,1,225k,weareallsatoshi@getalby.com,2024-07-31
OneOneSeven117,issue,#1272,#1268,easy,,,,10k,OneOneSeven@stacker.news,2024-07-31
aniskhalfallah,pr,#1264,#1226,good-first-issue,,,,20k,aniskhalfallah@stacker.news,2024-07-31
Gudnessuche,issue,#1264,#1226,good-first-issue,,,,2k,???,???

1 name type pr id issue ids difficulty priority changes requested notes amount receive method date paid
115 kravhen pr #1215 #253 medium 2 upgraded to medium 200k nichro@getalby.com 2024-06-28
116 dillon-co pr #1140 #633 hard requested advance 500k bolt11 2024-07-02
117 takitakitanana issue #1257 good-first-issue 2k takitakitanana@stacker.news 2024-07-11
118 SatsAllDay pr #1263 #1112 medium 1 225k weareallsatoshi@getalby.com 2024-07-31
119 OneOneSeven117 issue #1272 #1268 easy 10k OneOneSeven@stacker.news 2024-07-31
120 aniskhalfallah pr #1264 #1226 good-first-issue 20k aniskhalfallah@stacker.news 2024-07-31
121 Gudnessuche issue #1264 #1226 good-first-issue 2k ??? ???

View File

@ -29,7 +29,7 @@ export default function Qr ({ asIs, value, useWallet: automated, statusVariant,
className='h-auto mw-100' value={qrValue} renderAs='svg' size={300} className='h-auto mw-100' value={qrValue} renderAs='svg' size={300}
/> />
</a> </a>
{description && <div className='mt-1 fst-italic text-center text-muted'>{description}</div>} {description && <div className='mt-1 text-center text-muted'>{description}</div>}
<div className='mt-3 w-100'> <div className='mt-3 w-100'>
<CopyInput type='text' placeholder={value} readOnly noForm /> <CopyInput type='text' placeholder={value} readOnly noForm />
</div> </div>

View File

@ -67,10 +67,10 @@ export function DropdownItemUpVote ({ item }) {
) )
} }
export const defaultTipIncludingRandom = ({ tipDefault, tipRandom, tipRandomMin, tipRandomMax }) => export const defaultTipIncludingRandom = ({ tipDefault, tipRandom, tipRandomMin, tipRandomMax } = {}) =>
tipRandom tipRandom
? Math.floor((Math.random() * (tipRandomMax - tipRandomMin)) + tipRandomMin) ? Math.floor((Math.random() * (tipRandomMax - tipRandomMin)) + tipRandomMin)
: (tipDefault || 1) : (tipDefault || 100)
export const nextTip = (meSats, { tipDefault, turboTipping, tipRandom, tipRandomMin, tipRandomMax }) => { export const nextTip = (meSats, { tipDefault, turboTipping, tipRandom, tipRandomMin, tipRandomMax }) => {
// what should our next tip be? // what should our next tip be?

View File

@ -150,6 +150,8 @@ services:
env_file: *env_file env_file: *env_file
environment: environment:
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh - OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh
- plugins.security.disabled=true
- discovery.type=single-node
ports: ports:
- 9200:9200 # REST API - 9200:9200 # REST API
- 9600:9600 # Performance Analyzer - 9600:9600 # Performance Analyzer

View File

@ -36,12 +36,12 @@ export const numWithUnits = (n, {
abbreviate = true, abbreviate = true,
unitSingular = 'sat', unitSingular = 'sat',
unitPlural = 'sats', unitPlural = 'sats',
format = false format
} = {}) => { } = {}) => {
if (isNaN(n)) { if (isNaN(n)) {
return `${n} ${unitPlural}` return `${n} ${unitPlural}`
} }
return `${abbreviate ? abbrNum(n) : format ? new Intl.NumberFormat().format(n) : n} ${n === 1 ? unitSingular : unitPlural}` return `${abbreviate ? abbrNum(n) : !abbreviate || format === true ? new Intl.NumberFormat().format(n) : n} ${n === 1 ? unitSingular : unitPlural}`
} }
export const fixedDecimal = (n, f) => { export const fixedDecimal = (n, f) => {

6
lib/sndev.js Normal file
View File

@ -0,0 +1,6 @@
export function isServiceEnabled (service) {
if (process.env.NODE_ENV !== 'development') return true
const services = (process.env.COMPOSE_PROFILES ?? '').split(',')
return services.includes(service)
}

11
sndev
View File

@ -1,6 +1,11 @@
#!/bin/sh #!/bin/sh
set -e set -e
set -a # automatically export all variables
. .env.development
if [ -f .env.local ]; then
. .env.local
fi
docker__compose() { docker__compose() {
if [ ! -x "$(command -v docker)" ]; then if [ ! -x "$(command -v docker)" ]; then
@ -9,16 +14,12 @@ docker__compose() {
exit 0 exit 0
fi fi
if [ -z "$COMPOSE_PROFILES" ]; then
COMPOSE_PROFILES="images,search,payments,wallets,email,capture"
fi
ENV_LOCAL= ENV_LOCAL=
if [ -f .env.local ]; then if [ -f .env.local ]; then
ENV_LOCAL='--env-file .env.local' ENV_LOCAL='--env-file .env.local'
fi fi
CURRENT_UID=$(id -u) CURRENT_GID=$(id -g) COMPOSE_PROFILES=$COMPOSE_PROFILES command docker compose --env-file .env.development $ENV_LOCAL "$@" CURRENT_UID=$(id -u) CURRENT_GID=$(id -g) command docker compose --env-file .env.development $ENV_LOCAL "$@"
} }
docker__exec() { docker__exec() {

View File

@ -27,6 +27,7 @@ import { saltAndHashEmails } from './saltAndHashEmails.js'
import { remindUser } from './reminder.js' import { remindUser } from './reminder.js'
import { holdAction, settleAction, settleActionError } from './paidAction.js' import { holdAction, settleAction, settleActionError } from './paidAction.js'
import { thisDay } from './thisDay.js' import { thisDay } from './thisDay.js'
import { isServiceEnabled } from '@/lib/sndev.js'
const { loadEnvConfig } = nextEnv const { loadEnvConfig } = nextEnv
const { ApolloClient, HttpLink, InMemoryCache } = apolloClient const { ApolloClient, HttpLink, InMemoryCache } = apolloClient
@ -82,17 +83,29 @@ async function work () {
await boss.start() await boss.start()
await subscribeToWallet(args) if (isServiceEnabled('payments')) {
await boss.work('finalizeHodlInvoice', jobWrapper(finalizeHodlInvoice)) await subscribeToWallet(args)
await boss.work('checkPendingDeposits', jobWrapper(checkPendingDeposits)) await boss.work('finalizeHodlInvoice', jobWrapper(finalizeHodlInvoice))
await boss.work('checkPendingWithdrawals', jobWrapper(checkPendingWithdrawals)) await boss.work('checkPendingDeposits', jobWrapper(checkPendingDeposits))
await boss.work('autoDropBolt11s', jobWrapper(autoDropBolt11s)) await boss.work('checkPendingWithdrawals', jobWrapper(checkPendingWithdrawals))
await boss.work('autoWithdraw', jobWrapper(autoWithdraw)) await boss.work('autoDropBolt11s', jobWrapper(autoDropBolt11s))
await boss.work('autoWithdraw', jobWrapper(autoWithdraw))
await boss.work('settleActionError', jobWrapper(settleActionError))
await boss.work('settleAction', jobWrapper(settleAction))
await boss.work('checkInvoice', jobWrapper(checkInvoice))
await boss.work('holdAction', jobWrapper(holdAction))
}
if (isServiceEnabled('search')) {
await boss.work('indexItem', jobWrapper(indexItem))
await boss.work('indexAllItems', jobWrapper(indexAllItems))
}
if (isServiceEnabled('images')) {
await boss.work('imgproxy', jobWrapper(imgproxy))
await boss.work('deleteUnusedImages', jobWrapper(deleteUnusedImages))
}
await boss.work('repin-*', jobWrapper(repin)) await boss.work('repin-*', jobWrapper(repin))
await boss.work('trust', jobWrapper(trust)) await boss.work('trust', jobWrapper(trust))
await boss.work('timestampItem', jobWrapper(timestampItem)) await boss.work('timestampItem', jobWrapper(timestampItem))
await boss.work('indexItem', jobWrapper(indexItem))
await boss.work('indexAllItems', jobWrapper(indexAllItems))
await boss.work('auction', jobWrapper(auction)) await boss.work('auction', jobWrapper(auction))
await boss.work('earn', jobWrapper(earn)) await boss.work('earn', jobWrapper(earn))
await boss.work('streak', jobWrapper(computeStreaks)) await boss.work('streak', jobWrapper(computeStreaks))
@ -100,18 +113,12 @@ async function work () {
await boss.work('nip57', jobWrapper(nip57)) await boss.work('nip57', jobWrapper(nip57))
await boss.work('views-*', jobWrapper(views)) await boss.work('views-*', jobWrapper(views))
await boss.work('rankViews', jobWrapper(rankViews)) await boss.work('rankViews', jobWrapper(rankViews))
await boss.work('imgproxy', jobWrapper(imgproxy))
await boss.work('deleteItem', jobWrapper(deleteItem)) await boss.work('deleteItem', jobWrapper(deleteItem))
await boss.work('deleteUnusedImages', jobWrapper(deleteUnusedImages))
await boss.work('territoryBilling', jobWrapper(territoryBilling)) await boss.work('territoryBilling', jobWrapper(territoryBilling))
await boss.work('territoryRevenue', jobWrapper(territoryRevenue)) await boss.work('territoryRevenue', jobWrapper(territoryRevenue))
await boss.work('ofac', jobWrapper(ofac)) await boss.work('ofac', jobWrapper(ofac))
await boss.work('saltAndHashEmails', jobWrapper(saltAndHashEmails)) await boss.work('saltAndHashEmails', jobWrapper(saltAndHashEmails))
await boss.work('reminder', jobWrapper(remindUser)) await boss.work('reminder', jobWrapper(remindUser))
await boss.work('settleActionError', jobWrapper(settleActionError))
await boss.work('settleAction', jobWrapper(settleAction))
await boss.work('holdAction', jobWrapper(holdAction))
await boss.work('checkInvoice', jobWrapper(checkInvoice))
await boss.work('thisDay', jobWrapper(thisDay)) await boss.work('thisDay', jobWrapper(thisDay))
console.log('working jobs') console.log('working jobs')