mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo-client.git
synced 2026-09-21 16:52:02 -07:00
Specify Like / Tip a Memo
By specifier.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# psf-memo-db changes to support Like counts
|
||||
|
||||
**Status**: DRAFT — notes for a future session. The current Like/Tip feature
|
||||
(`0x6d04`) focuses on the **UI to broadcast a like** (and an optional tip). The
|
||||
read-side changes below are **not** implemented now; they are recorded here so the
|
||||
like-count read path can be developed later.
|
||||
|
||||
Owner: specifier.
|
||||
Last updated: 2026-08-26.
|
||||
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Expose like counts (and, later, liked-state and a likers list) so the psf-memo-client
|
||||
UI can show a real like count on each post and whether the viewing user already liked
|
||||
it. Today `/posts/*` responses omit likes entirely.
|
||||
|
||||
## What the indexer already provides
|
||||
|
||||
The Memo **indexer** (`psf-memo-indexer`) already parses `0x6d04` like/tip actions into
|
||||
the DB as social references: a **liker address** → a **liked post txid** (with an
|
||||
optional tip value). This feature does not require indexer changes to record likes; it
|
||||
requires the **DB query/API** layer to aggregate and expose them.
|
||||
|
||||
## Required psf-memo-db changes
|
||||
|
||||
1. **`likeCount` on post responses.**
|
||||
Add a `likeCount` field (number of distinct `0x6d04` references whose liked txid
|
||||
equals the post txid) to the objects returned by:
|
||||
- `/posts/recent` (feed items)
|
||||
- `/post/:txid` (thread root)
|
||||
- thread reply nodes (when replies are also likeable / shown with counts)
|
||||
Aggregate the count in the query rather than an N+1 per-post lookup.
|
||||
|
||||
2. **Liked-state for the viewing user (optional, later).**
|
||||
To render a filled heart when the current wallet has already liked a post, the
|
||||
read endpoints need to know the viewer. Add an optional `viewer=<address>` query
|
||||
param (or equivalent) to the relevant post endpoints and return
|
||||
`liked: true|false` per post based on whether `viewer` has a `0x6d04` reference to
|
||||
that txid. Until this exists, the client can track "liked" locally/optimistically
|
||||
for the current session only.
|
||||
|
||||
3. **Likers list endpoint (later).**
|
||||
memo.cash shows a modal listing who liked a post (its `post/likes`). Add an endpoint
|
||||
e.g. `GET /post/:txid/likes` returning `[{ address, name, profilePicUrl, tip }...]`
|
||||
for the addresses that liked the post, ordered by time/tip, joined with the profile
|
||||
store to avoid N+1 lookups. Used by a future "likes" modal.
|
||||
|
||||
4. **Join efficiency.**
|
||||
Like counts must be aggregated server-side (e.g. a counter derived from the
|
||||
reference index or a materialized count) and included in the same response as the
|
||||
post text, author, name, and avatar — avoid N+1 per-item like lookups in feed and
|
||||
thread responses.
|
||||
|
||||
## Out of scope (this session)
|
||||
|
||||
- The like-count **read surface** (count badge, liked-state, likers modal).
|
||||
- `viewer` liked-state param.
|
||||
- Likers list endpoint.
|
||||
|
||||
All of the above are future work; the UI spec for this session only broadcasts the
|
||||
like/tip and increments a count **optimistically**.
|
||||
@@ -0,0 +1,112 @@
|
||||
# Scenarios: Like / Tip a Memo - 1, Like / Tip a Memo - 2, Like / Tip a Memo - 3, Like / Tip a Memo - 4, Like / Tip a Memo - 5, Like / Tip a Memo - 6, Like / Tip a Memo - 7, Like / Tip a Memo - 8, Like / Tip a Memo - 9, Like / Tip a Memo - 10
|
||||
Feature: Like / Tip a Memo
|
||||
|
||||
Background:
|
||||
Given a wallet authenticated for the address bitcoincash:qqlrzp23w08434twmvr4fxw672whkjy0py26r63g3d
|
||||
Given the wallet has a spendable balance of 100000 sats
|
||||
Given a post with the txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa authored by the author address
|
||||
|
||||
Scenario: Like / Tip a Memo - 1 the heart icon opens the like/tip modal
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
Then a like/tip modal opens for the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 2 a pure like broadcasts the Memo like action
|
||||
Given a post with the txid <txid> authored by the author address
|
||||
When I click the heart icon on the post with txid <txid>
|
||||
When I submit the like without a tip
|
||||
Then the wallet broadcasts an OP_RETURN transaction with the Memo like prefix and the post txid <txid>
|
||||
Then the wallet sends no tip
|
||||
Then the like count on the post increases by one
|
||||
Then the heart icon on the post shows as filled
|
||||
|
||||
Examples:
|
||||
| txid |
|
||||
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
|
||||
| bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb |
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 3 a like with a tip broadcasts and pays the author
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
When I enter a tip of <tip>
|
||||
When I submit the like
|
||||
Then the wallet broadcasts an OP_RETURN transaction with the Memo like prefix and the post txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
Then the wallet sends a tip of <tip> to the author address
|
||||
Then the like count on the post increases by one
|
||||
Then the heart icon on the post shows as filled
|
||||
|
||||
Examples:
|
||||
| tip |
|
||||
| 3000 |
|
||||
| 25000 |
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 4 an invalid tip is rejected
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
When I enter a tip of <tip>
|
||||
When I submit the like
|
||||
Then the like/tip modal shows an error containing "valid number"
|
||||
Then the wallet does not broadcast any transaction
|
||||
|
||||
Examples:
|
||||
| tip |
|
||||
| 1.5 |
|
||||
| abc |
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 5 a tip below the dust limit is rejected
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
When I enter a tip of <tip>
|
||||
When I submit the like
|
||||
Then the like/tip modal shows an error containing "dust limit"
|
||||
Then the wallet does not broadcast any transaction
|
||||
|
||||
Examples:
|
||||
| tip |
|
||||
| 1 |
|
||||
| 2999 |
|
||||
|
||||
Scenario: Like / Tip a Memo - 6 a tip above the maximum is rejected
|
||||
Given the wallet has a spendable balance of 150000000 sats
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
When I enter a tip of 100000001
|
||||
When I submit the like
|
||||
Then the like/tip modal shows an error containing "maximum"
|
||||
Then the wallet does not broadcast any transaction
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 7 a tip above the spendable balance is rejected
|
||||
Given the wallet has a spendable balance of <balance> sats
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
When I enter a tip of <tip>
|
||||
When I submit the like
|
||||
Then the like/tip modal shows an error containing "spendable"
|
||||
Then the wallet does not broadcast any transaction
|
||||
|
||||
Examples:
|
||||
| balance | tip |
|
||||
| 30000 | 35000 |
|
||||
| 500000 | 550000 |
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 8 a user without spendable balance cannot like
|
||||
Given the wallet has a spendable balance of <balance> sats
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
Then the like/tip modal shows an error containing "add BCH"
|
||||
Then the wallet does not broadcast any transaction
|
||||
|
||||
Examples:
|
||||
| balance |
|
||||
| 0 |
|
||||
| 2999 |
|
||||
|
||||
Scenario Outline: Like / Tip a Memo - 9 a user can like their own post
|
||||
Given a post with the txid <txid> authored by my address
|
||||
When I click the heart icon on the post with txid <txid>
|
||||
When I submit the like without a tip
|
||||
Then the wallet broadcasts an OP_RETURN transaction with the Memo like prefix and the post txid <txid>
|
||||
Then the like count on the post increases by one
|
||||
|
||||
Examples:
|
||||
| txid |
|
||||
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
|
||||
| bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb |
|
||||
|
||||
Scenario: Like / Tip a Memo - 10 the cancel button closes the like/tip modal
|
||||
When I click the heart icon on the post with txid aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
When I click the cancel button
|
||||
Then the like/tip modal closes
|
||||
Reference in New Issue
Block a user