Compare commits

...

14 Commits

Author SHA1 Message Date
Keyan
0d93c92e30
Merge pull request #1971 from stackernews/fix-anon-failed-invoices
Don't poll failed invoices if anon
2025-03-12 20:25:12 -05:00
ekzyis
6f50b485b4 Don't poll failed invoices if anon 2025-03-12 20:10:15 -05:00
Keyan
6715943862
Merge pull request #1970 from stackernews/reply-cost-check
Add check for Sub.replyCost > 0
2025-03-12 19:46:47 -05:00
Keyan
dbce0a7517
Merge pull request #1969 from stackernews/fix-saloon-replies
Fix saloon replies
2025-03-12 19:46:21 -05:00
ekzyis
4e62053b45 Fix saloon replies
The query will return { replyCost: null } if no sub was found because of the left join.
2025-03-12 17:53:39 -05:00
ekzyis
a9943981fd Add check for Sub.replyCost > 0 2025-03-12 17:53:15 -05:00
ekzyis
2038701ecf
Merge pull request #1968 from stackernews/faq-update
Update FAQ with wallet questions
2025-03-12 17:44:59 -05:00
ekzyis
b46418e71e Shorten question 2025-03-12 15:14:57 -05:00
ekzyis
907a7aabbd Update FAQ with wallet questions 2025-03-12 15:13:27 -05:00
Keyan
8f8b2e4496
Merge pull request #1966 from stackernews/rename-to-next-account
Rename to /api/next-account
2025-03-11 07:56:46 -05:00
ekzyis
69e62c1e6e Rename to /api/next-account 2025-03-10 20:24:13 -05:00
Keyan
9aad2fd903
Merge pull request #1963 from stackernews/fix-item-cost
Fix item cost in details
2025-03-10 20:03:48 -05:00
k00b
ed9fa5f823 fix fragment when comment visited directly + one db dip 2025-03-10 20:02:55 -05:00
ekzyis
65b1db23a7 Fix item cost in details 2025-03-10 18:13:33 -05:00
7 changed files with 39 additions and 16 deletions

View File

@ -20,18 +20,15 @@ export async function getBaseCost ({ models, bio, parentId, subName }) {
if (parentId) {
// the subname is stored in the root item of the thread
const parent = await models.item.findFirst({
where: { id: Number(parentId) },
include: {
root: { include: { sub: true } },
sub: true
}
})
const [sub] = await models.$queryRaw`
SELECT s."replyCost"
FROM "Item" i
LEFT JOIN "Item" r ON r.id = i."rootId"
LEFT JOIN "Sub" s ON s.name = COALESCE(r."subName", i."subName")
WHERE i.id = ${Number(parentId)}`
const root = parent.root ?? parent
if (!root.sub) return DEFAULT_ITEM_COST
return satsToMsats(root.sub.replyCost)
if (sub?.replyCost) return satsToMsats(sub.replyCost)
return DEFAULT_ITEM_COST
}
const sub = await models.sub.findUnique({ where: { name: subName } })

View File

@ -51,7 +51,7 @@ export const AccountProvider = ({ children }) => {
}, [])
const multiAuthSignout = useCallback(async () => {
const { status } = await fetch('/api/signout', { credentials: 'include' })
const { status } = await fetch('/api/next-account', { credentials: 'include' })
// if status is 302, this means the server was able to switch us to the next available account
// and the current account was simply removed from the list of available accounts including the corresponding JWT.
const switchSuccess = status === 302

View File

@ -8,7 +8,7 @@ sub: meta
_To quickly browse through this FAQ page, click the chapters icon in the top-right corner. This will let you scroll through all chapters or search for a particular topic within this page._
last updated: February 7, 2025
last updated: March 12, 2025
---
@ -174,6 +174,26 @@ This can happen for any of the following reasons:
You cannot disable receiving CCs but we might change that in the future. For now, you can donate any CCs you received [here](/rewards).
### If I attach a wallet, do I always pay with sats?
No. We will only try to pay with sats from your wallet when you zap other stackers. In any other case, you're paying us, Stacker News, and we will thus try to first use any CCs you already have. If you don't have enough CCs, we will fallback to your attached wallet.
### Can I pay only the remainder with sats?
No. Payments can currently only be made entirely in CCs or sats.
### Which wallet is used if I attached multiple wallets for send or receive?
All of them! The wallet that is the furthest to the top-right will be attempted first. If it fails, we will attempt the next wallet in order. On desktop, you can drag the wallets around to rearrange their priority. On mobile, you need to click on a wallet and then select where you want the wallet to be.
These sender and receiver fallbacks happen if the payment failed for any reason. The sender will attempt the next wallet if the error was caused by the sender side and the same is true for the receiver.
The only limitation is that we will currently not attempt to pay with CCs at the end once we started to try paying with sats but all wallets failed. This will change in the future.
### Are payments retried in the background?
Yes. We try each payment three times in total with all sender and receiver fallbacks. If a payment still wasn't successful after that, you will receive a notification allowing you to retry the payment manually.
---
## Territories
@ -249,7 +269,7 @@ The info text mentions that you will inherit all existing content.
Other than that, the process to bring back an archived territory is the same as founding a new territory.
### I want to share the costs and revenue of a territory with someone. How do I do that?
### Can I share the costs and revenue of a territory with someone?
You can't do that yet but this is planned. Currently, territories can only have a single founder.

View File

@ -108,6 +108,7 @@ export const ITEM_FULL_FIELDS = gql`
moderated
meMuteSub
meSubscription
replyCost
}
}
forwards {

View File

@ -1,5 +1,5 @@
import * as cookie from 'cookie'
import { datePivot } from '../../lib/time'
import { datePivot } from '@/lib/time'
/**
* @param {NextApiRequest} req

View File

@ -0,0 +1,2 @@
-- Add constraint to ensure replyCost is positive
ALTER TABLE "Sub" ADD CONSTRAINT "Sub_replyCost_positive" CHECK ("replyCost" > 0);

View File

@ -236,6 +236,7 @@ function RetryHandler ({ children }) {
const waitForWalletPayment = useWalletPayment()
const invoiceHelper = useInvoice()
const [getFailedInvoices] = useLazyQuery(FAILED_INVOICES, { fetchPolicy: 'network-only', nextFetchPolicy: 'network-only' })
const { me } = useMe()
const retry = useCallback(async (invoice) => {
const newInvoice = await invoiceHelper.retry({ ...invoice, newAttempt: true })
@ -255,6 +256,8 @@ function RetryHandler ({ children }) {
// we always retry failed invoices, even if the user has no wallets on any client
// to make sure that failed payments will always show up in notifications eventually
if (!me) return
const retryPoll = async () => {
let failedInvoices
try {
@ -298,7 +301,7 @@ function RetryHandler ({ children }) {
queuePoll()
return stopPolling
}, [wallets, getFailedInvoices, retry])
}, [me?.id, wallets, getFailedInvoices, retry])
return children
}