Compare commits
5 Commits
dc0370ba17
...
8000886e72
Author | SHA1 | Date | |
---|---|---|---|
|
8000886e72 | ||
|
4b391dd6ee | ||
|
e6f6895ce0 | ||
|
837767a323 | ||
|
7901f2fe61 |
@ -1,6 +1,7 @@
|
||||
PRISMA_SLOW_LOGS_MS=
|
||||
GRAPHQL_SLOW_LOGS_MS=
|
||||
NODE_ENV=development
|
||||
COMPOSE_PROFILES='minimal,images,search,payments,wallets,email,capture'
|
||||
|
||||
############################################################################
|
||||
# OPTIONAL SECRETS #
|
||||
@ -114,8 +115,6 @@ POSTGRES_DB=stackernews
|
||||
|
||||
# opensearch container stuff
|
||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh
|
||||
plugins.security.disabled=true
|
||||
discovery.type=single-node
|
||||
DISABLE_SECURITY_DASHBOARDS_PLUGIN=true
|
||||
|
||||
# bitcoind container stuff
|
||||
|
24
README.md
24
README.md
@ -76,6 +76,7 @@ COMMANDS
|
||||
|
||||
sn:
|
||||
login login as a nym
|
||||
fund_user fund a nym without using an LN invoice
|
||||
|
||||
lnd:
|
||||
fund pay a bolt11 for funding
|
||||
@ -92,12 +93,14 @@ COMMANDS
|
||||
dev:
|
||||
pr fetch and checkout a pr
|
||||
lint run linters
|
||||
open open container url in browser
|
||||
|
||||
other:
|
||||
compose docker compose passthrough
|
||||
sn_lndcli lncli passthrough on sn_lnd
|
||||
stacker_lndcli lncli passthrough on stacker_lnd
|
||||
stacker_clncli lightning-cli passthrough on stacker_cln
|
||||
stacker_litcli litcli passthrough on litd
|
||||
|
||||
```
|
||||
|
||||
@ -105,23 +108,16 @@ COMMANDS
|
||||
|
||||
#### 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
|
||||
$ COMPOSE_PROFILES=minimal ./sndev start
|
||||
```
|
||||
|
||||
Or, as I would recommend:
|
||||
|
||||
```sh
|
||||
$ export COMPOSE_PROFILES=minimal
|
||||
$ ./sndev start
|
||||
```.env
|
||||
COMPOSE_PROFILES=minimal
|
||||
```
|
||||
|
||||
To run with images and payments services:
|
||||
|
||||
```sh
|
||||
$ COMPOSE_PROFILES=images,payments ./sndev start
|
||||
```.env
|
||||
COMPOSE_PROFILES=images,payments
|
||||
```
|
||||
|
||||
#### Merging compose files
|
||||
@ -460,7 +456,9 @@ In addition, we run other critical services the above services interact with lik
|
||||
|
||||
## 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>
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
import lndService from 'ln-service'
|
||||
import lnd from '@/api/lnd'
|
||||
import { isServiceEnabled } from '@/lib/sndev'
|
||||
|
||||
const cache = new Map()
|
||||
const expiresIn = 1000 * 30 // 30 seconds in milliseconds
|
||||
|
||||
async function fetchBlockHeight () {
|
||||
let blockHeight = 0
|
||||
if (!isServiceEnabled('payments')) return blockHeight
|
||||
try {
|
||||
const height = await lndService.getHeight({ lnd })
|
||||
blockHeight = height.current_block_height
|
||||
|
@ -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
|
||||
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
|
||||
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,???,???
|
||||
|
|
@ -29,7 +29,7 @@ export default function Qr ({ asIs, value, useWallet: automated, statusVariant,
|
||||
className='h-auto mw-100' value={qrValue} renderAs='svg' size={300}
|
||||
/>
|
||||
</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'>
|
||||
<CopyInput type='text' placeholder={value} readOnly noForm />
|
||||
</div>
|
||||
|
@ -67,10 +67,10 @@ export function DropdownItemUpVote ({ item }) {
|
||||
)
|
||||
}
|
||||
|
||||
export const defaultTipIncludingRandom = ({ tipDefault, tipRandom, tipRandomMin, tipRandomMax }) =>
|
||||
export const defaultTipIncludingRandom = ({ tipDefault, tipRandom, tipRandomMin, tipRandomMax } = {}) =>
|
||||
tipRandom
|
||||
? Math.floor((Math.random() * (tipRandomMax - tipRandomMin)) + tipRandomMin)
|
||||
: (tipDefault || 1)
|
||||
: (tipDefault || 100)
|
||||
|
||||
export const nextTip = (meSats, { tipDefault, turboTipping, tipRandom, tipRandomMin, tipRandomMax }) => {
|
||||
// what should our next tip be?
|
||||
|
@ -150,6 +150,8 @@ services:
|
||||
env_file: *env_file
|
||||
environment:
|
||||
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=mVchg1T5oA9wudUh
|
||||
- plugins.security.disabled=true
|
||||
- discovery.type=single-node
|
||||
ports:
|
||||
- 9200:9200 # REST API
|
||||
- 9600:9600 # Performance Analyzer
|
||||
|
@ -36,12 +36,12 @@ export const numWithUnits = (n, {
|
||||
abbreviate = true,
|
||||
unitSingular = 'sat',
|
||||
unitPlural = 'sats',
|
||||
format = false
|
||||
format
|
||||
} = {}) => {
|
||||
if (isNaN(n)) {
|
||||
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) => {
|
||||
|
6
lib/sndev.js
Normal file
6
lib/sndev.js
Normal 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
11
sndev
@ -1,6 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
set -a # automatically export all variables
|
||||
. .env.development
|
||||
if [ -f .env.local ]; then
|
||||
. .env.local
|
||||
fi
|
||||
|
||||
docker__compose() {
|
||||
if [ ! -x "$(command -v docker)" ]; then
|
||||
@ -9,16 +14,12 @@ docker__compose() {
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$COMPOSE_PROFILES" ]; then
|
||||
COMPOSE_PROFILES="images,search,payments,wallets,email,capture"
|
||||
fi
|
||||
|
||||
ENV_LOCAL=
|
||||
if [ -f .env.local ]; then
|
||||
ENV_LOCAL='--env-file .env.local'
|
||||
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() {
|
||||
|
@ -27,6 +27,7 @@ import { saltAndHashEmails } from './saltAndHashEmails.js'
|
||||
import { remindUser } from './reminder.js'
|
||||
import { holdAction, settleAction, settleActionError } from './paidAction.js'
|
||||
import { thisDay } from './thisDay.js'
|
||||
import { isServiceEnabled } from '@/lib/sndev.js'
|
||||
|
||||
const { loadEnvConfig } = nextEnv
|
||||
const { ApolloClient, HttpLink, InMemoryCache } = apolloClient
|
||||
@ -82,17 +83,29 @@ async function work () {
|
||||
|
||||
await boss.start()
|
||||
|
||||
await subscribeToWallet(args)
|
||||
await boss.work('finalizeHodlInvoice', jobWrapper(finalizeHodlInvoice))
|
||||
await boss.work('checkPendingDeposits', jobWrapper(checkPendingDeposits))
|
||||
await boss.work('checkPendingWithdrawals', jobWrapper(checkPendingWithdrawals))
|
||||
await boss.work('autoDropBolt11s', jobWrapper(autoDropBolt11s))
|
||||
await boss.work('autoWithdraw', jobWrapper(autoWithdraw))
|
||||
if (isServiceEnabled('payments')) {
|
||||
await subscribeToWallet(args)
|
||||
await boss.work('finalizeHodlInvoice', jobWrapper(finalizeHodlInvoice))
|
||||
await boss.work('checkPendingDeposits', jobWrapper(checkPendingDeposits))
|
||||
await boss.work('checkPendingWithdrawals', jobWrapper(checkPendingWithdrawals))
|
||||
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('trust', jobWrapper(trust))
|
||||
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('earn', jobWrapper(earn))
|
||||
await boss.work('streak', jobWrapper(computeStreaks))
|
||||
@ -100,18 +113,12 @@ async function work () {
|
||||
await boss.work('nip57', jobWrapper(nip57))
|
||||
await boss.work('views-*', jobWrapper(views))
|
||||
await boss.work('rankViews', jobWrapper(rankViews))
|
||||
await boss.work('imgproxy', jobWrapper(imgproxy))
|
||||
await boss.work('deleteItem', jobWrapper(deleteItem))
|
||||
await boss.work('deleteUnusedImages', jobWrapper(deleteUnusedImages))
|
||||
await boss.work('territoryBilling', jobWrapper(territoryBilling))
|
||||
await boss.work('territoryRevenue', jobWrapper(territoryRevenue))
|
||||
await boss.work('ofac', jobWrapper(ofac))
|
||||
await boss.work('saltAndHashEmails', jobWrapper(saltAndHashEmails))
|
||||
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))
|
||||
|
||||
console.log('working jobs')
|
||||
|
Loading…
x
Reference in New Issue
Block a user