@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.d.mts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +143 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +143 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +56 -0
- package/src/hooks/useCreateGame.ts +10 -3
- package/src/hooks/useJoinGame.ts +3 -0
- package/src/types.ts +29 -0
- package/src/ui/game/CreateGameSheet.tsx +49 -4
- package/src/ui/game/JoinGameSheet.tsx +82 -4
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
|
|
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 ${
|
|
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:
|
|
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
|
-
|
|
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 && !
|
|
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
|
-
|
|
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__ */
|
|
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 },
|