|
| 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