Skip to content

Commit 13989b0

Browse files
db/workflows: hodler verify + token balances RLS
Why: - Track SEND balances and hodler verification to support rewards logic while preserving precision. - Keep balances/weights as string|bigint end‑to‑end to avoid Number coercion and on‑chain precision loss. - Use a token_key for reliable upserts (ERC‑20 and native) under a single unique key; avoid NULL‑uniqueness pitfalls and complex partial indexes. - Update only on deposits in receive triggers; internal transfers are handled by workflows, preventing double counting. - Do not backfill send_token_hodler into past distributions; require it only for new distributions (id >= 21). Changes: - Temporal workflows - Add readBalanceActivity and persistBalanceActivity (SEND‑only, gated via base chain and sendTokenAddress). - Add upsertSendTokenHodlerVerificationActivity and apply to both sender and receiver post‑confirmation. - Fix dvError handling; remove stray casts; wire error handling via isRetryableDBError. - Types & lint - Widen Supabase overrides so writes accept number|string|bigint for token_balances.balance and distribution_verifications.weight; keep generated Row types as number. - Remove problematic casts/usages; escape quotes; simplify imports; fix onScrub prop usage; yarn lint passes cleanly. - Schema & migrations - Create token_balances with RLS, generated token_key, and unique (user_id,token_key) for simple upserts; add helpful indexes. - Add deposit‑only trigger on send_account_receives to upsert native balances; exclude internal transfers (sender is a Send Account). - Fix backfill CTE scope (eth_dep) to avoid relation errors; keep new hodler backfill a no‑op. - Tests - Add pgtap test asserting send_token_hodler exists for all distributions with id >= 21. Test plan: - yarn lint → no errors. - yarn supabase test → distribution_send_token_hodler_test passes; other tag tests remain unchanged. - Manual: run a SEND transfer; verify: - token_balances upserted for both addresses (correct user, chain, token/native), RLS allows owner to read. - distribution_verifications upserted for both parties with type send_token_hodler and weight preserved as string|bigint.
1 parent bd1e2e0 commit 13989b0

File tree

15 files changed

+1552
-163
lines changed

15 files changed

+1552
-163
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Temporal-driven SEND balances and hodler verification
2+
3+
Summary
4+
- Move from DB-advancer to Temporal-driven updates that read balanceOf at transfer confirmation.
5+
- Track only SEND token for now; persist balances into public.token_balances and upsert distribution_verifications type=send_token_hodler with weight=balance.
6+
- Enable RLS so users can SELECT their own balances directly.
7+
8+
Scope (phase 0–2)
9+
- SEND-only, ERC-20 balanceOf via configured RPC; native ETH/outside ERC-20s are out-of-scope for this PR (design leaves room to support later).
10+
- Persist for `from` always; also persist for `to` only when both are Send Accounts.
11+
- Read point: after receipt is available (no additional confirmations for now).
12+
- DB reads: direct SELECT from public.token_balances (RLS enforced: user sees own rows only).
13+
14+
What changes
15+
- Temporal transfer workflow (packages/workflows/src/transfer-workflow/workflow.ts):
16+
- After a transfer is confirmed, add two activities per applicable participant:
17+
1) readAndPersistBalance (reads balanceOf for SEND token, upserts public.token_balances)
18+
2) upsertSendTokenHodlerVerification (upserts distribution_verifications with type=send_token_hodler, weight=balance)
19+
- Only execute when decoded token is the SEND token for the active chain; skip otherwise.
20+
- Apply to `from`; apply to `to` only if it’s also a Send Account.
21+
- Activities (packages/workflows/src/transfer-workflow/activities.ts):
22+
- Implement readAndPersistBalance using existing wagmi patterns (distribution-workflow/wagmi.ts → readSendTokenBalanceOf) and Supabase admin upsert (pattern from deposit-workflow/activities.ts).
23+
- Implement upsertSendTokenHodlerVerification with ON CONFLICT (distribution_id, user_id, type) DO UPDATE; metadata NULL, weight=balance.
24+
- Resolve current distribution at run-time (qualification window contains now()).
25+
- Database (supabase/migrations/*):
26+
- Add enum value send_token_hodler to verification_type.
27+
- Enable RLS on public.token_balances and add policy: authenticated users can SELECT their own rows.
28+
29+
Out of scope (future increments)
30+
- Cleanup of prior advancer/cursor/functions/views (not needed here since we branch off dev without those).
31+
- Native ETH and arbitrary ERC-20 support: design notes indicate token can be NULL in token_balances for ETH; actual schema change is deferred to a follow-up PR to avoid breaking PK (user_id, token). For now, SEND-only means token remains NOT NULL.
32+
- One-shot/batch backfill workflow to seed balances before deploying Temporal path (to be implemented after core activities land).
33+
34+
Why this correlates to existing patterns
35+
- Activities DB write patterns mirror deposit-workflow/activities.ts (Supabase admin, retryable vs non-retryable ApplicationFailure).
36+
- balanceOf reads mirror distribution-workflow/wagmi.ts (readSendTokenBalanceOf(config, { args: [address], chainId })).
37+
- Upsert patterns for public tables mirror prior direct inserts in deposit activities (e.g., referrals) and composite ON CONFLICT strategies used elsewhere.
38+
39+
Test plan (high level)
40+
- Migration:
41+
- Apply migration in staging; verify new enum value; verify RLS policy allows only own rows.
42+
- Workflow (staging):
43+
- Perform a SEND token transfer between two Send Accounts; observe public.token_balances updated for both; distribution_verifications row upserted for type=send_token_hodler with weight=balance.
44+
- Perform a SEND token transfer where `to` is not a Send Account; observe balance persisted for `from` only.
45+
- Backfill (later PR):
46+
- Run one-shot workflow to seed balances; verify rows inserted/updated and verifications optionally upserted.

0 commit comments

Comments
 (0)