Skip to content

Commit c40377b

Browse files
Merge pull request #25 from reserve-protocol/chore/success
Feat: inline success view + post-mint contact panel
2 parents cf14b7e + 4c102e7 commit c40377b

30 files changed

Lines changed: 964 additions & 924 deletions

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
## [2.1.0] - 2026-06-04
2+
3+
### Added
4+
5+
- Post-transaction success view: on a confirmed zap the Zapper keeps the flow in place and shows what actually happened. The boxes switch to "You used" / "You received", the received amount is read from the transaction logs (the exact output token credited to the wallet) with the realized price impact, the quote details are hidden, and an inline success bar (`✓ Successful Purchase` / `Successful Sale`) links to the block explorer. Reopening the Zapper starts fresh.
6+
- After a mint, a "Stay informed" contact-capture panel where users can leave a Telegram, X, or email contact to receive updates about the DTF. On wider screens (≥900px) in modal/simple mode it slides out from behind the modal (secondary background) and the modal+panel pair recenters; inline mode and narrow screens render it as a stacked card. Toggle with the new `showContactInfo` prop (defaults to `true`). Submissions POST to Reserve's storage worker and fail silently for the user.
7+
- Mixpanel events for the contact feature (`tap` event, `subpage: 'contact'`): `zap_contact_submit`, `zap_contact_subscribed`, `zap_contact_error`, each carrying `ca`, `ticker`, `chain`, and the chosen `platform`.
8+
9+
### Removed
10+
11+
- **Breaking:** removed the `Toaster` export and the `sonner` / `next-themes` dependencies. The package no longer renders toasts; success and errors are shown inline. Remove any `import { Toaster } from '@reserve-protocol/react-zapper'` and its usage — you no longer need to mount a toaster or install `sonner`.
12+
113
## [2.0.0] - 2026-06-02
214

315
### Breaking Changes

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ context — it does **not** create its own. You provide a `WagmiProvider` and a
3939
Import the components you need and the CSS file for styling:
4040

4141
```tsx
42-
import { Zapper, useZapperModal, Toaster } from '@reserve-protocol/react-zapper'
42+
import { Zapper, useZapperModal } from '@reserve-protocol/react-zapper'
4343
import '@reserve-protocol/react-zapper/styles.css'
4444
```
4545

@@ -88,7 +88,7 @@ function App({ children }: { children: React.ReactNode }) {
8888
### 2. Basic Modal Usage
8989

9090
```tsx
91-
import { Zapper, useZapperModal, Toaster } from '@reserve-protocol/react-zapper'
91+
import { Zapper, useZapperModal } from '@reserve-protocol/react-zapper'
9292
import '@reserve-protocol/react-zapper/styles.css'
9393

9494
function MyApp() {
@@ -103,8 +103,6 @@ function MyApp() {
103103
/>
104104

105105
<button onClick={open}>Open Zapper</button>
106-
107-
<Toaster position="bottom-right" />
108106
</>
109107
)
110108
}
@@ -162,6 +160,7 @@ Simple mode features:
162160
| `zapperApiUrl` | `string` || Custom zapper service endpoint for zapper-specific API calls (falls back to `apiUrl`) |
163161
| `sellOnly` | `boolean` || Only show the sell (redeem) flow |
164162
| `disabled` | `boolean` || Disable primary zap actions, wallet/chain actions, amount inputs, and Max buttons |
163+
| `showContactInfo`| `boolean` || Show the "Stay informed" contact-capture panel after a successful mint (defaults to `true`) |
165164
| `connectWallet` | `() => void` || Function to trigger wallet connection |
166165
| `debug` | `boolean` || Enable debug mode to show additional info |
167166
| `defaultSource` | `QuoteSource` || Default quote source: `'best'` (compare all enabled providers), `'zap'`, `'odos'`, `'velora'`, or `'enso'` |
@@ -260,21 +259,22 @@ package's internal state); no extra providers are required.
260259

261260
## Advanced Usage
262261

263-
### With Custom Error Handling
262+
### Transaction Feedback
264263

265-
```tsx
266-
import { Zapper, Toaster } from '@reserve-protocol/react-zapper'
267-
import { toast } from 'sonner'
264+
The Zapper renders all transaction feedback inline — no toaster setup required
265+
(there is no `Toaster` export and `sonner` is no longer a dependency).
268266

269-
function AdvancedZapper() {
270-
return (
271-
<>
272-
<Zapper chain={1} dtfAddress="0x123..." mode="modal" />
273-
<Toaster />
274-
</>
275-
)
276-
}
277-
```
267+
On a successful transaction the flow stays in place and switches to a success
268+
view: the boxes read "You used" / "You received", the received amount is taken
269+
from the transaction logs (the exact output token credited to the wallet) with
270+
the realized price impact, and an inline success bar links to the block explorer.
271+
Errors are rendered inline as well. The state resets when the Zapper is
272+
closed/reopened.
273+
274+
After a mint, a "Stay informed" panel lets users leave a contact (Telegram, X, or
275+
email) for DTF updates. Hide it with `showContactInfo={false}`. Submissions fail
276+
silently for the user and emit Mixpanel events (`zap_contact_submit`,
277+
`zap_contact_subscribed`, `zap_contact_error`).
278278

279279
### With Custom API Endpoint
280280

demo/App.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { ConnectButton } from '@rainbow-me/rainbowkit'
22
import {
3-
Toaster,
43
useZapperModal,
54
PROVIDERS,
65
type ProviderId,
@@ -72,6 +71,7 @@ function App() {
7271
const [zapperApiUrl, setZapperApiUrl] = useState(ZAPPER_API_URLS[0].value)
7372
const [mode, setMode] = useState<'modal' | 'inline' | 'simple'>('inline')
7473
const [sellOnly, setSellOnly] = useState(false)
74+
const [showContactInfo, setShowContactInfo] = useState(true)
7575
const { open } = useZapperModal()
7676

7777
// Update selected DTF when chain changes
@@ -314,6 +314,33 @@ function App() {
314314
When enabled, disables Buy tab and only allows selling/redeeming
315315
</p>
316316
</div>
317+
<div>
318+
<label className="text-sm font-medium mb-2 block">
319+
Show Contact Info
320+
</label>
321+
<Select
322+
value={showContactInfo.toString()}
323+
onValueChange={(value) =>
324+
setShowContactInfo(value === 'true')
325+
}
326+
>
327+
<SelectTrigger className="w-full md:w-96">
328+
<SelectValue />
329+
</SelectTrigger>
330+
<SelectContent>
331+
{[true, false]
332+
.map((v) => v.toString())
333+
.map((v) => (
334+
<SelectItem key={v} value={v}>
335+
{v}
336+
</SelectItem>
337+
))}
338+
</SelectContent>
339+
</Select>
340+
<p className="text-xs text-muted-foreground mt-1">
341+
Shows the "Stay informed" contact panel after a successful mint
342+
</p>
343+
</div>
317344
</CardContent>
318345
</Card>
319346

@@ -346,6 +373,7 @@ function App() {
346373
defaultSource={quoteSource}
347374
debug={debug}
348375
sellOnly={sellOnly}
376+
showContactInfo={showContactInfo}
349377
/>
350378
<Button onClick={open} className="w-full rounded-xl" size="lg">
351379
Open Zapper Modal
@@ -362,6 +390,7 @@ function App() {
362390
debug={debug}
363391
defaultSource={quoteSource}
364392
sellOnly={sellOnly}
393+
showContactInfo={showContactInfo}
365394
/>
366395
</div>
367396
)}
@@ -372,7 +401,6 @@ function App() {
372401
</>
373402
)}
374403
</div>
375-
<Toaster position="bottom-right" />
376404
</div>
377405
)
378406
}

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@reserve-protocol/react-zapper",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"type": "module",
55
"packageManager": "pnpm@11.1.1",
66
"description": "React component for DTF minting with zap functionality",
@@ -67,8 +67,6 @@
6767
"jotai": "^1.12.0",
6868
"lucide-react": "^0.461.0",
6969
"mixpanel-browser": "^2.56.0",
70-
"next-themes": "^0.2.1",
71-
"sonner": "^1.4.0",
7270
"tailwind-merge": "^2.5.5",
7371
"uuid": "^13.0.0"
7472
},

0 commit comments

Comments
 (0)