@dubsdotapp/expo 0.5.32 → 0.5.34

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.
package/dist/index.mjs CHANGED
@@ -257,6 +257,22 @@ var DubsClient = class {
257
257
  };
258
258
  }
259
259
  async createGame(params) {
260
+ if (params.useCredit) {
261
+ const res2 = await this.request("POST", "/games/create-sponsored", {
262
+ id: params.id,
263
+ teamChoice: params.teamChoice
264
+ });
265
+ return {
266
+ gameId: res2.gameId,
267
+ gameAddress: res2.gameAddress,
268
+ transaction: res2.transaction,
269
+ lockTimestamp: res2.lockTimestamp,
270
+ event: res2.event,
271
+ promoCode: res2.promoCode,
272
+ sponsorWallet: res2.sponsorWallet,
273
+ wagerAmount: res2.wagerAmount
274
+ };
275
+ }
260
276
  const res = await this.request(
261
277
  "POST",
262
278
  "/games/create",
@@ -271,6 +287,19 @@ var DubsClient = class {
271
287
  };
272
288
  }
273
289
  async joinGame(params) {
290
+ if (params.useCredit) {
291
+ const res2 = await this.request("POST", "/games/join-sponsored", {
292
+ gameId: params.gameId,
293
+ teamChoice: params.teamChoice
294
+ });
295
+ return {
296
+ gameId: res2.gameId,
297
+ transaction: res2.transaction,
298
+ gameAddress: res2.gameAddress,
299
+ promoCode: res2.promoCode,
300
+ sponsorWallet: res2.sponsorWallet
301
+ };
302
+ }
274
303
  const res = await this.request(
275
304
  "POST",
276
305
  "/games/join",
@@ -2074,14 +2103,18 @@ function useCreateGame() {
2074
2103
  console.log("[useCreateGame] Step 2 done. Signature:", signature);
2075
2104
  setStatus("confirming");
2076
2105
  console.log("[useCreateGame] Step 3: Confirming with backend...");
2106
+ const wagerAmount = createResult.wagerAmount ?? params.wagerAmount;
2077
2107
  const confirmResult = await client.confirmGame({
2078
2108
  gameId: createResult.gameId,
2079
2109
  playerWallet: params.playerWallet,
2080
2110
  signature,
2081
2111
  teamChoice: params.teamChoice,
2082
- wagerAmount: params.wagerAmount,
2112
+ wagerAmount,
2083
2113
  role: "creator",
2084
- gameAddress: createResult.gameAddress
2114
+ gameAddress: createResult.gameAddress,
2115
+ // Echo the credit code through so the server marks it as used
2116
+ // after the on-chain confirm succeeds.
2117
+ promoCode: createResult.promoCode
2085
2118
  });
2086
2119
  console.log("[useCreateGame] Step 3 done.");
2087
2120
  const result = {
@@ -2098,14 +2131,14 @@ function useCreateGame() {
2098
2131
  const home = event?.opponents?.[0]?.name ?? null;
2099
2132
  const away = event?.opponents?.[1]?.name ?? null;
2100
2133
  const teamLabel = params.teamChoice === "home" ? teamNickname(home) : params.teamChoice === "away" ? teamNickname(away) : "Draw";
2101
- const message = `I just placed a ${params.wagerAmount} SOL bet on ${teamLabel} - Join me!`;
2134
+ const message = `I just placed a ${wagerAmount} SOL bet on ${teamLabel} - Join me!`;
2102
2135
  const gameInvite = {
2103
2136
  gameId: createResult.gameId,
2104
2137
  gameAddress: createResult.gameAddress,
2105
2138
  title: event?.title,
2106
2139
  league: event?.league,
2107
2140
  gameType: "sports",
2108
- buyIn: params.wagerAmount,
2141
+ buyIn: wagerAmount,
2109
2142
  status: "waiting",
2110
2143
  homeTeam: home,
2111
2144
  awayTeam: away,
@@ -2170,7 +2203,10 @@ function useJoinGame() {
2170
2203
  teamChoice: params.teamChoice,
2171
2204
  wagerAmount: params.amount,
2172
2205
  role: "joiner",
2173
- gameAddress: joinResult.gameAddress
2206
+ gameAddress: joinResult.gameAddress,
2207
+ // Pass through when this was a sponsored join — server marks
2208
+ // the credit as used after the on-chain confirm succeeds.
2209
+ promoCode: joinResult.promoCode
2174
2210
  };
2175
2211
  console.log("[useJoinGame] Step 3: Confirming with backend...", confirmParams);
2176
2212
  const confirmResult = await client.confirmGame(confirmParams);
@@ -6044,10 +6080,14 @@ function JoinGameSheet({
6044
6080
  const t = useDubsTheme();
6045
6081
  const { wallet } = useDubs();
6046
6082
  const mutation = useJoinGame();
6083
+ const { credits, refetch: refetchCredits } = useCredits();
6047
6084
  const isCustomGame = game.gameMode === CUSTOM_GAME_MODE;
6048
6085
  const [selectedTeam, setSelectedTeam] = useState35(null);
6049
6086
  const [wager, setWager] = useState35(game.buyIn);
6050
6087
  const [showSuccess, setShowSuccess] = useState35(false);
6088
+ const [useCredit, setUseCredit] = useState35(false);
6089
+ const oldestCredit = credits.length > 0 ? credits[0] : null;
6090
+ const canUseCredit = !!oldestCredit && Math.round(oldestCredit.amountSOL * 1e9) >= Math.round(game.buyIn * 1e9);
6051
6091
  const overlayOpacity = useRef10(new Animated4.Value(0)).current;
6052
6092
  const successScale = useRef10(new Animated4.Value(0)).current;
6053
6093
  const successOpacity = useRef10(new Animated4.Value(0)).current;
@@ -6136,11 +6176,15 @@ function JoinGameSheet({
6136
6176
  playerWallet: wallet.publicKey.toBase58(),
6137
6177
  gameId: game.gameId,
6138
6178
  teamChoice: selectedTeam,
6139
- amount: wager
6179
+ // When useCredit is on, the on-chain instruction transfers
6180
+ // exactly the credit's amount; pass that as the wager.
6181
+ amount: useCredit && oldestCredit ? oldestCredit.amountSOL : wager,
6182
+ useCredit: useCredit && canUseCredit ? true : void 0
6140
6183
  });
6184
+ if (useCredit) refetchCredits();
6141
6185
  } catch {
6142
6186
  }
6143
- }, [selectedTeam, wallet.publicKey, mutation.execute, game.gameId, wager]);
6187
+ }, [selectedTeam, wallet.publicKey, mutation.execute, game.gameId, wager, useCredit, oldestCredit, canUseCredit, refetchCredits]);
6144
6188
  const statusLabel = STATUS_LABELS3[mutation.status] || "";
6145
6189
  return /* @__PURE__ */ jsxs15(
6146
6190
  Modal3,
@@ -6343,7 +6387,26 @@ function JoinGameSheet({
6343
6387
  ] })
6344
6388
  ] })
6345
6389
  ] }),
6346
- selectedTeam && !isPoolModeEnabled && !alreadyJoined && /* @__PURE__ */ jsx18(
6390
+ selectedTeam && !alreadyJoined && canUseCredit && oldestCredit && /* @__PURE__ */ jsxs15(
6391
+ TouchableOpacity11,
6392
+ {
6393
+ style: [styles15.creditRow, { backgroundColor: useCredit ? "#22C55E18" : t.surface, borderColor: useCredit ? "#22C55E" : t.border }],
6394
+ activeOpacity: 0.8,
6395
+ onPress: () => setUseCredit((v) => !v),
6396
+ children: [
6397
+ /* @__PURE__ */ jsxs15(View16, { style: styles15.creditRowText, children: [
6398
+ /* @__PURE__ */ jsxs15(Text16, { style: [styles15.creditTitle, { color: useCredit ? "#22C55E" : t.text }], children: [
6399
+ "\u{1F381} Use my ",
6400
+ formatSol(oldestCredit.amountSOL),
6401
+ " SOL credit"
6402
+ ] }),
6403
+ /* @__PURE__ */ jsx18(Text16, { style: [styles15.creditSub, { color: t.textMuted }], children: useCredit ? "Treasury covers this bet \u2014 wager locked to credit amount" : `${credits.length} credit${credits.length === 1 ? "" : "s"} available from your streak` })
6404
+ ] }),
6405
+ /* @__PURE__ */ jsx18(View16, { style: [styles15.creditCheckbox, useCredit && { backgroundColor: "#22C55E", borderColor: "#22C55E" }], children: useCredit && /* @__PURE__ */ jsx18(Text16, { style: styles15.creditCheck, children: "\u2713" }) })
6406
+ ]
6407
+ }
6408
+ ),
6409
+ selectedTeam && !isPoolModeEnabled && !alreadyJoined && !useCredit && /* @__PURE__ */ jsx18(
6347
6410
  SolSlider,
6348
6411
  {
6349
6412
  value: wager,
@@ -6681,6 +6744,41 @@ var styles15 = StyleSheet16.create({
6681
6744
  flexDirection: "row",
6682
6745
  alignItems: "center",
6683
6746
  gap: 10
6747
+ },
6748
+ creditRow: {
6749
+ flexDirection: "row",
6750
+ alignItems: "center",
6751
+ gap: 12,
6752
+ marginTop: 12,
6753
+ padding: 12,
6754
+ borderRadius: 12,
6755
+ borderWidth: 1.5
6756
+ },
6757
+ creditRowText: {
6758
+ flex: 1,
6759
+ gap: 2
6760
+ },
6761
+ creditTitle: {
6762
+ fontSize: 14,
6763
+ fontWeight: "700"
6764
+ },
6765
+ creditSub: {
6766
+ fontSize: 12,
6767
+ fontWeight: "500"
6768
+ },
6769
+ creditCheckbox: {
6770
+ width: 22,
6771
+ height: 22,
6772
+ borderRadius: 11,
6773
+ borderWidth: 2,
6774
+ borderColor: "#3A3A3C",
6775
+ alignItems: "center",
6776
+ justifyContent: "center"
6777
+ },
6778
+ creditCheck: {
6779
+ color: "#FFFFFF",
6780
+ fontSize: 14,
6781
+ fontWeight: "900"
6684
6782
  }
6685
6783
  });
6686
6784
 
@@ -7542,9 +7640,13 @@ function CreateGameSheet({
7542
7640
  const t = useDubsTheme();
7543
7641
  const { wallet } = useDubs();
7544
7642
  const mutation = useCreateGame();
7643
+ const { credits, refetch: refetchCredits } = useCredits();
7545
7644
  const [selectedTeam, setSelectedTeam] = useState39(null);
7546
7645
  const [wager, setWager] = useState39(0.01);
7547
7646
  const [showSuccess, setShowSuccess] = useState39(false);
7647
+ const [useCredit, setUseCredit] = useState39(false);
7648
+ const oldestCredit = credits.length > 0 ? credits[0] : null;
7649
+ const canUseCredit = !!oldestCredit;
7548
7650
  const overlayOpacity = useRef14(new Animated8.Value(0)).current;
7549
7651
  const successScale = useRef14(new Animated8.Value(0)).current;
7550
7652
  const successOpacity = useRef14(new Animated8.Value(0)).current;
@@ -7599,11 +7701,16 @@ function CreateGameSheet({
7599
7701
  id: event.id,
7600
7702
  playerWallet: wallet.publicKey.toBase58(),
7601
7703
  teamChoice: selectedTeam,
7602
- wagerAmount: wager
7704
+ // When sponsoring, the on-chain instruction forces buy-in to
7705
+ // the credit's amount; pass that so client-side wager state
7706
+ // matches what gets recorded.
7707
+ wagerAmount: useCredit && oldestCredit ? oldestCredit.amountSOL : wager,
7708
+ useCredit: useCredit && canUseCredit ? true : void 0
7603
7709
  });
7710
+ if (useCredit) refetchCredits();
7604
7711
  } catch {
7605
7712
  }
7606
- }, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager]);
7713
+ }, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager, useCredit, oldestCredit, canUseCredit, refetchCredits]);
7607
7714
  const statusLabel = STATUS_LABELS6[mutation.status] || "";
7608
7715
  const startTime = event.startTime ? new Date(event.startTime) : null;
7609
7716
  const timeLabel = startTime ? startTime.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" }) + " at " + startTime.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }) : "TBD";
@@ -7678,7 +7785,26 @@ function CreateGameSheet({
7678
7785
  /* @__PURE__ */ jsx23(Text21, { style: [styles20.summaryValue, { color: t.success }], children: "Set the odds" })
7679
7786
  ] })
7680
7787
  ] }),
7681
- selectedTeam && /* @__PURE__ */ jsx23(
7788
+ selectedTeam && canUseCredit && oldestCredit && /* @__PURE__ */ jsxs20(
7789
+ TouchableOpacity16,
7790
+ {
7791
+ style: [styles20.creditRow, { backgroundColor: useCredit ? "#22C55E18" : t.surface, borderColor: useCredit ? "#22C55E" : t.border }],
7792
+ activeOpacity: 0.8,
7793
+ onPress: () => setUseCredit((v) => !v),
7794
+ children: [
7795
+ /* @__PURE__ */ jsxs20(View20, { style: styles20.creditRowText, children: [
7796
+ /* @__PURE__ */ jsxs20(Text21, { style: [styles20.creditTitle, { color: useCredit ? "#22C55E" : t.text }], children: [
7797
+ "\u{1F381} Use my ",
7798
+ formatSol2(oldestCredit.amountSOL),
7799
+ " SOL credit"
7800
+ ] }),
7801
+ /* @__PURE__ */ jsx23(Text21, { style: [styles20.creditSub, { color: t.textMuted }], children: useCredit ? "Treasury covers rent + buy-in" : `${credits.length} credit${credits.length === 1 ? "" : "s"} from your streak` })
7802
+ ] }),
7803
+ /* @__PURE__ */ jsx23(View20, { style: [styles20.creditCheckbox, useCredit && { backgroundColor: "#22C55E", borderColor: "#22C55E" }], children: useCredit && /* @__PURE__ */ jsx23(Text21, { style: styles20.creditCheck, children: "\u2713" }) })
7804
+ ]
7805
+ }
7806
+ ),
7807
+ selectedTeam && !useCredit && /* @__PURE__ */ jsx23(
7682
7808
  SolSlider,
7683
7809
  {
7684
7810
  value: wager,
@@ -7732,6 +7858,12 @@ var styles20 = StyleSheet21.create({
7732
7858
  ctaButton: { marginTop: 16, height: 54, borderRadius: 14, justifyContent: "center", alignItems: "center" },
7733
7859
  ctaText: { color: "#FFFFFF", fontSize: 16, fontWeight: "700" },
7734
7860
  ctaLoading: { flexDirection: "row", alignItems: "center", gap: 10 },
7861
+ creditRow: { flexDirection: "row", alignItems: "center", gap: 12, marginTop: 12, padding: 12, borderRadius: 12, borderWidth: 1.5 },
7862
+ creditRowText: { flex: 1, gap: 2 },
7863
+ creditTitle: { fontSize: 14, fontWeight: "700" },
7864
+ creditSub: { fontSize: 12, fontWeight: "500" },
7865
+ creditCheckbox: { width: 22, height: 22, borderRadius: 11, borderWidth: 2, borderColor: "#3A3A3C", alignItems: "center", justifyContent: "center" },
7866
+ creditCheck: { color: "#FFFFFF", fontSize: 14, fontWeight: "900" },
7735
7867
  successOverlay: { ...StyleSheet21.absoluteFillObject, zIndex: 100, alignItems: "center", justifyContent: "center", backgroundColor: "rgba(0,0,0,0.85)" },
7736
7868
  successContent: { alignItems: "center", gap: 12 },
7737
7869
  successEmoji: { fontSize: 64 },