@dubsdotapp/expo 0.2.42 → 0.2.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +160 -3
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -117,6 +117,8 @@ function CreateBet({ eventId }: { eventId: string }) {
117
117
  | `renderError` | `fn` | *default UI* | Custom error screen |
118
118
  | `renderRegistration` | `fn` | *default UI* | Custom registration screen |
119
119
  | `managed` | `boolean` | `true` | Set `false` for headless mode (no connect screen or auth gate) |
120
+ | `redirectUri` | `string` | — | Deeplink redirect URI for Phantom wallet (required for iOS) |
121
+ | `appUrl` | `string` | — | App URL shown in Phantom's connect screen |
120
122
 
121
123
  ### Disconnect
122
124
 
@@ -178,12 +180,16 @@ const myStorage: TokenStorage = {
178
180
 
179
181
  | Hook | Type | Description |
180
182
  |------|------|-------------|
183
+ | `useAuth()` | Auth | Full auth state — `user`, `isAuthenticated`, `authenticate()`, `register()`, `logout()` |
181
184
  | `useEvents(params?)` | Query | Fetch upcoming events (sports + esports) |
182
185
  | `useGame(gameId)` | Query | Single game detail |
183
186
  | `useGames(params?)` | Query | List games with filters |
184
- | `useCreateGame()` | Mutation | Full create lifecycle (build sign send → confirm) |
185
- | `useJoinGame()` | Mutation | Full join lifecycle |
186
- | `useClaim()` | Mutation | Full claim lifecycle |
187
+ | `useNetworkGames(params?)` | Query | List games across the entire Dubs network |
188
+ | `useCreateGame()` | Mutation | Create game on a sports/esports event (build → sign → confirm) |
189
+ | `useCreateCustomGame()` | Mutation | Create a custom 1v1 game with arbitrary buy-in |
190
+ | `useJoinGame()` | Mutation | Join an existing game |
191
+ | `useClaim()` | Mutation | Claim prize or refund after game resolves |
192
+ | `useHasClaimed(gameId)` | Query | Check if current wallet already claimed — returns `hasClaimed`, `amountClaimed`, `claimSignature` |
187
193
 
188
194
  ### Mutation Status
189
195
 
@@ -208,6 +214,157 @@ const game = await client.getGame('sport-123...');
208
214
  const codes = client.getErrorCodesLocal();
209
215
  ```
210
216
 
217
+ ## UI Components
218
+
219
+ ### Game Sheets
220
+
221
+ Drop-in bottom sheets that handle the full transaction lifecycle (build → sign → confirm) internally.
222
+
223
+ #### CreateCustomGameSheet
224
+
225
+ Bottom sheet for creating a custom 1v1 game with configurable buy-in.
226
+
227
+ ```tsx
228
+ import { CreateCustomGameSheet } from '@dubsdotapp/expo';
229
+
230
+ <CreateCustomGameSheet
231
+ visible={showSheet}
232
+ onDismiss={() => setShowSheet(false)}
233
+ presetAmounts={[0.01, 0.1, 0.5]}
234
+ defaultAmount={0.01}
235
+ metadata={{ matchType: 'battleship' }}
236
+ onSuccess={(result) => console.log('Created!', result.gameId)}
237
+ onError={(err) => console.error(err)}
238
+ />
239
+ ```
240
+
241
+ | Prop | Type | Default | Description |
242
+ |------|------|---------|-------------|
243
+ | `visible` | `boolean` | *required* | Show/hide the sheet |
244
+ | `onDismiss` | `() => void` | *required* | Called when user closes the sheet |
245
+ | `title` | `string` | `'New Game'` | Sheet header title |
246
+ | `maxPlayers` | `number` | `2` | Max players (currently 1v1) |
247
+ | `fee` | `number` | `0.05` | Platform fee percentage (0–1) |
248
+ | `presetAmounts` | `number[]` | `[0.01, 0.1, 0.5]` | Quick-select buy-in chips |
249
+ | `defaultAmount` | `number` | — | Pre-selected buy-in |
250
+ | `metadata` | `Record<string, unknown>` | — | Arbitrary metadata attached to the game |
251
+ | `onSuccess` | `(result) => void` | — | Called with `{ gameId, gameAddress, signature, explorerUrl, buyIn }` |
252
+ | `onError` | `(error) => void` | — | Called on failure |
253
+
254
+ #### JoinGameSheet
255
+
256
+ Bottom sheet for joining an existing game. Shows buy-in, team selection, pool summary, and potential winnings.
257
+
258
+ ```tsx
259
+ import { JoinGameSheet } from '@dubsdotapp/expo';
260
+
261
+ <JoinGameSheet
262
+ visible={showSheet}
263
+ onDismiss={() => setShowSheet(false)}
264
+ game={gameData}
265
+ onSuccess={(result) => console.log('Joined!', result.signature)}
266
+ onError={(err) => console.error(err)}
267
+ />
268
+ ```
269
+
270
+ | Prop | Type | Default | Description |
271
+ |------|------|---------|-------------|
272
+ | `visible` | `boolean` | *required* | Show/hide the sheet |
273
+ | `onDismiss` | `() => void` | *required* | Called when user closes the sheet |
274
+ | `game` | `GameDetail` | *required* | Game data from `useGame()` |
275
+ | `ImageComponent` | `ComponentType` | — | Custom image component (e.g. expo-image) for team logos |
276
+ | `shortName` | `(name) => string` | — | Custom team label formatter |
277
+ | `homeColor` | `string` | `'#3B82F6'` | Home team accent color |
278
+ | `awayColor` | `string` | `'#EF4444'` | Away team accent color |
279
+ | `onSuccess` | `(result) => void` | — | Called with `{ signature, explorerUrl }` |
280
+ | `onError` | `(error) => void` | — | Called on failure |
281
+
282
+ #### ClaimPrizeSheet
283
+
284
+ Bottom sheet for claiming a prize or refund after a game resolves. Includes a celebration animation on success.
285
+
286
+ ```tsx
287
+ import { ClaimPrizeSheet } from '@dubsdotapp/expo';
288
+
289
+ <ClaimPrizeSheet
290
+ visible={showSheet}
291
+ onDismiss={() => setShowSheet(false)}
292
+ gameId="abc123..."
293
+ prizeAmount={0.019}
294
+ isRefund={false}
295
+ onSuccess={(result) => console.log('Claimed!', result.explorerUrl)}
296
+ />
297
+ ```
298
+
299
+ | Prop | Type | Default | Description |
300
+ |------|------|---------|-------------|
301
+ | `visible` | `boolean` | *required* | Show/hide the sheet |
302
+ | `onDismiss` | `() => void` | *required* | Called when user closes the sheet |
303
+ | `gameId` | `string` | *required* | Game ID to claim |
304
+ | `prizeAmount` | `number` | *required* | Prize amount in SOL |
305
+ | `isRefund` | `boolean` | `false` | Show refund language instead of prize language |
306
+ | `onSuccess` | `(result) => void` | — | Called with `{ signature, explorerUrl }` |
307
+ | `onError` | `(error) => void` | — | Called on failure |
308
+
309
+ ### ClaimButton
310
+
311
+ Drop-in button that handles the entire claim flow internally — eligibility checks, prize/refund display, sheet lifecycle, and claimed badge. Renders nothing when the user is ineligible.
312
+
313
+ ```tsx
314
+ import { ClaimButton } from '@dubsdotapp/expo';
315
+
316
+ <ClaimButton
317
+ gameId="abc123..."
318
+ onSuccess={(result) => console.log('Claimed!', result.explorerUrl)}
319
+ onError={(err) => console.error(err)}
320
+ />
321
+ ```
322
+
323
+ | Prop | Type | Default | Description |
324
+ |------|------|---------|-------------|
325
+ | `gameId` | `string` | *required* | Game ID to check and claim |
326
+ | `style` | `ViewStyle` | — | Custom button style |
327
+ | `onSuccess` | `(result) => void` | — | Called after successful claim |
328
+ | `onError` | `(error) => void` | — | Called on failure |
329
+
330
+ **Render states:**
331
+ - Loading / no wallet / no data → renders nothing
332
+ - Not eligible (lost, not resolved, not a bettor) → renders nothing
333
+ - Eligible + unclaimed → solid accent button: "Claim Prize — X SOL" or "Claim Refund — X SOL"
334
+ - Already claimed → outlined badge: "Prize Claimed!" or "Refund Claimed!"
335
+
336
+ ### Game Display Cards
337
+
338
+ | Component | Description |
339
+ |-----------|-------------|
340
+ | `GamePoster` | Hero card with team logos, names, countdown, and live/locked badges |
341
+ | `LivePoolsCard` | Pool breakdown — each side's SOL amount, bar chart, and implied odds |
342
+ | `PickWinnerCard` | Team selection card for choosing which side to bet on |
343
+ | `PlayersCard` | List of all bettors with avatar, username, team, and wager amount |
344
+ | `JoinGameButton` | Fixed bottom bar with buy-in info and join CTA (hides when already joined / locked / resolved) |
345
+
346
+ ### Profile & Settings
347
+
348
+ | Component | Description |
349
+ |-----------|-------------|
350
+ | `UserProfileCard` | Displays avatar, username, wallet address, and member-since date |
351
+ | `SettingsSheet` | Full settings screen with profile card, copy address, support link, and logout |
352
+
353
+ ### Theming
354
+
355
+ All UI components respect the developer-configured accent color from the Dubs dashboard. You can also override the theme programmatically:
356
+
357
+ ```tsx
358
+ import { useDubsTheme, mergeTheme } from '@dubsdotapp/expo';
359
+ import type { DubsTheme } from '@dubsdotapp/expo';
360
+
361
+ // Inside a component — automatically respects light/dark mode + accent override
362
+ const theme = useDubsTheme();
363
+
364
+ // Or merge custom overrides manually
365
+ const custom = mergeTheme(baseTheme, { accent: '#EF4444' });
366
+ ```
367
+
211
368
  ## Event ID Format
212
369
 
213
370
  - Sports: `sports:{LEAGUE}:{EVENT_ID}` (e.g. `sports:NBA:espn-nba-401...`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dubsdotapp/expo",
3
- "version": "0.2.42",
3
+ "version": "0.2.43",
4
4
  "description": "React Native SDK for the Dubs betting platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",