feat(campaign): Juicer NFT campaign backend (/v1/campaigns/juicer/*)#269
Open
joshuakrueger-dfx wants to merge 1 commit into
Open
feat(campaign): Juicer NFT campaign backend (/v1/campaigns/juicer/*)#269joshuakrueger-dfx wants to merge 1 commit into
joshuakrueger-dfx wants to merge 1 commit into
Conversation
The Juicer NFT page (bapp#741) and JuicerNFT.sol (smart-contracts#56) were both built against a campaign backend that didn't exist. This adds it, mirroring the First Squeezer patterns: - GET /progress — composes Ponder-earned JP, the JpSpend ledger, social verification and on-chain hasClaimed into the page's read model (availableJp = earned - spent) - POST /spend — atomic, idempotent 5,000 JP trade; the (walletAddress, chainId, reason) unique constraint dedupes retries and concurrent inserts (P2002); fails closed when Ponder is down - POST /twitter/mark-followed — honor-system X follow (First Squeezer parity), on the Juicer campaign record - GET /discord/start|callback — Discord OAuth requiring the Juicer role; one Discord account per wallet - GET /nft/signature — EIP-191 signature for JuicerNFT.claim(); gates on spend + socials + meme-token (verified against Ponder, fails closed) + not-already-claimed New Prisma models: JuicerCampaignUser (social state, separate from OgCampaignUser so campaigns don't bleed) and JpSpend (the authoritative off-chain spend side of the JP economy). DiscordOAuthService gains an optional per-flow callback override that is persisted in the OAuth session, because Discord requires the token exchange to repeat the authorize-time redirect_uri exactly. Tests pin the claim-signature scheme to the contract's keccak256(abi.encodePacked(contract, chainid, wallet)) + EIP-191 recovery, including no-cross-use and case-insensitivity. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The missing backend for the Juicer NFT campaign. The frontend page (bapp#741) and JuicerNFT.sol (smart-contracts#56) were both built against /v1/campaigns/juicer/* endpoints that did not exist. This adds them, mirroring the First Squeezer patterns.
Endpoints
Schema
New Prisma models JuicerCampaignUser and JpSpend (authoritative off-chain spend side). DiscordOAuthSession gains a callbackUrl column so a per-flow OAuth redirect survives the token exchange.
Wiring (required before claims work)
Tests
46/46 jest green incl. signature contract-compatibility. tsc clean. Prisma migration included.
Depends on JuiceSwapxyz/ponder#139 for the earn-side data.
🤖 Generated with Claude Code