feat(ads): rewarded video (VK) — client-attested credit + daily/hourly caps #228
Reference in New Issue
Block a user
Delete Branch "feature/ads-rewarded"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
First E6 (ads) slice — rewarded video. A voluntary VK rewarded video credits chips.
VK reality (checked in the VK docs via Playwright): VK Mini App ads expose only a client-side
data.result— no server verify. So the credit is client-attested (D29 amended), guarded by a server daily + hourly cap (configreward_daily_cap/reward_hourly_cap, default 50/10) — both anti-abuse (bounds a forger who skips the ad and calls the endpoint) and an economic conversion lever (limits free chips so players buy). Idempotent on a client nonce, order-less; payout from configrewarded_payout_chips(default 0 = off until set).CreditReward+wallet.rewardedge op (returns the wallet;reward_chipsgates the CTA). Additive migration (two config columns) → no contour wipe, rollback-safe.lib/ads.ts, VK impl) + VK bridge + Wallet "watch for chips" CTA + i18n.VITE_ADS_STUB→ toast instead of a real ad; prod always real — a failed real ad must not credit) + a temporary diagnostic that logs the raw VKdata.Tests: backend integration (credit / nonce-idempotent / hourly-cap / disabled / non-VK) + codec unit. Local: all Go build+vet+gofmt, backend unit, full payments integration, UI check+unit+build, bundle budget (shared 30→31). Docs: PAYMENTS(+ru) §10, D29 amend, PLAN E6.
Owner-side after deploy:
TEST_VITE_ADS_STUBunset) — crank a rewarded view; I read the logged raw VKdatato confirm what it returns (harden to signature if any).rewarded_payout_chips> 0 in the contour config to enable rewarded (go-live gate).TEST_VITE_ADS_STUB=1for routine toast-stub testing.Testing the rewarded slice surfaced a contradiction: rewarded ads let a VK-iOS user earn vk chips, but the blanket VK-iOS "spend freeze" then blocked spending them (the wallet showed "5 (view-only)"). Apple's ToS forbids only BUYING in-app values on VK-iOS (money -> chips), not spending or earning them — so the freeze is corrected to purchase-only: vkFrozen() now gates only CreateOrder (the money-in step), not spendableSources (spending). VK-wallet chips — earned via rewarded ads or bought on the same account elsewhere (VK Android) — now spend on VK-iOS too. (Owner's ToS finding.) Also: the temporary contour diagnostic confirmed VK returns only {result:true} for a rewarded view (no token/signature) — client-attested is final, no hardening possible — so the diagnostic (the log and the diag wire field) is removed. Docs: PAYMENTS(+ru) VK-iOS freeze + D17 amend + PLAN E6. Tests updated (gate / wallet VK-iOS now spendable).