@dubsdotapp/expo 0.5.33 → 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 +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +62 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +31 -0
- package/src/hooks/useCreateGame.ts +10 -3
- package/src/types.ts +13 -0
- package/src/ui/game/CreateGameSheet.tsx +49 -4
- package/src/ui/game/JoinGameSheet.tsx +6 -1
package/dist/index.d.mts
CHANGED
|
@@ -104,6 +104,14 @@ interface CreateGameParams {
|
|
|
104
104
|
playerWallet: string;
|
|
105
105
|
teamChoice: 'home' | 'away' | 'draw';
|
|
106
106
|
wagerAmount: number;
|
|
107
|
+
/**
|
|
108
|
+
* When true, fund create+join with one of the user's active 0.01 SOL
|
|
109
|
+
* streak credits instead of paying rent + buy-in from their own
|
|
110
|
+
* wallet. SDK picks the oldest credit (FIFO). Treasury covers rent
|
|
111
|
+
* + buy-in; player only signs to consent. Buy-in is forced to the
|
|
112
|
+
* credit amount.
|
|
113
|
+
*/
|
|
114
|
+
useCredit?: boolean;
|
|
107
115
|
}
|
|
108
116
|
interface CreateGameResult {
|
|
109
117
|
gameId: string;
|
|
@@ -111,6 +119,11 @@ interface CreateGameResult {
|
|
|
111
119
|
transaction: string;
|
|
112
120
|
lockTimestamp: number;
|
|
113
121
|
event: UnifiedEvent;
|
|
122
|
+
/** Set when sponsored — echoed back to confirmGame for mark-as-used. */
|
|
123
|
+
promoCode?: string;
|
|
124
|
+
sponsorWallet?: string;
|
|
125
|
+
/** Server-confirmed wager amount (== credit amount when sponsored). */
|
|
126
|
+
wagerAmount?: number;
|
|
114
127
|
}
|
|
115
128
|
interface CreateCustomGameParams {
|
|
116
129
|
playerWallet: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -104,6 +104,14 @@ interface CreateGameParams {
|
|
|
104
104
|
playerWallet: string;
|
|
105
105
|
teamChoice: 'home' | 'away' | 'draw';
|
|
106
106
|
wagerAmount: number;
|
|
107
|
+
/**
|
|
108
|
+
* When true, fund create+join with one of the user's active 0.01 SOL
|
|
109
|
+
* streak credits instead of paying rent + buy-in from their own
|
|
110
|
+
* wallet. SDK picks the oldest credit (FIFO). Treasury covers rent
|
|
111
|
+
* + buy-in; player only signs to consent. Buy-in is forced to the
|
|
112
|
+
* credit amount.
|
|
113
|
+
*/
|
|
114
|
+
useCredit?: boolean;
|
|
107
115
|
}
|
|
108
116
|
interface CreateGameResult {
|
|
109
117
|
gameId: string;
|
|
@@ -111,6 +119,11 @@ interface CreateGameResult {
|
|
|
111
119
|
transaction: string;
|
|
112
120
|
lockTimestamp: number;
|
|
113
121
|
event: UnifiedEvent;
|
|
122
|
+
/** Set when sponsored — echoed back to confirmGame for mark-as-used. */
|
|
123
|
+
promoCode?: string;
|
|
124
|
+
sponsorWallet?: string;
|
|
125
|
+
/** Server-confirmed wager amount (== credit amount when sponsored). */
|
|
126
|
+
wagerAmount?: number;
|
|
114
127
|
}
|
|
115
128
|
interface CreateCustomGameParams {
|
|
116
129
|
playerWallet: string;
|
package/dist/index.js
CHANGED
|
@@ -370,6 +370,22 @@ var DubsClient = class {
|
|
|
370
370
|
};
|
|
371
371
|
}
|
|
372
372
|
async createGame(params) {
|
|
373
|
+
if (params.useCredit) {
|
|
374
|
+
const res2 = await this.request("POST", "/games/create-sponsored", {
|
|
375
|
+
id: params.id,
|
|
376
|
+
teamChoice: params.teamChoice
|
|
377
|
+
});
|
|
378
|
+
return {
|
|
379
|
+
gameId: res2.gameId,
|
|
380
|
+
gameAddress: res2.gameAddress,
|
|
381
|
+
transaction: res2.transaction,
|
|
382
|
+
lockTimestamp: res2.lockTimestamp,
|
|
383
|
+
event: res2.event,
|
|
384
|
+
promoCode: res2.promoCode,
|
|
385
|
+
sponsorWallet: res2.sponsorWallet,
|
|
386
|
+
wagerAmount: res2.wagerAmount
|
|
387
|
+
};
|
|
388
|
+
}
|
|
373
389
|
const res = await this.request(
|
|
374
390
|
"POST",
|
|
375
391
|
"/games/create",
|
|
@@ -2180,14 +2196,18 @@ function useCreateGame() {
|
|
|
2180
2196
|
console.log("[useCreateGame] Step 2 done. Signature:", signature);
|
|
2181
2197
|
setStatus("confirming");
|
|
2182
2198
|
console.log("[useCreateGame] Step 3: Confirming with backend...");
|
|
2199
|
+
const wagerAmount = createResult.wagerAmount ?? params.wagerAmount;
|
|
2183
2200
|
const confirmResult = await client.confirmGame({
|
|
2184
2201
|
gameId: createResult.gameId,
|
|
2185
2202
|
playerWallet: params.playerWallet,
|
|
2186
2203
|
signature,
|
|
2187
2204
|
teamChoice: params.teamChoice,
|
|
2188
|
-
wagerAmount
|
|
2205
|
+
wagerAmount,
|
|
2189
2206
|
role: "creator",
|
|
2190
|
-
gameAddress: createResult.gameAddress
|
|
2207
|
+
gameAddress: createResult.gameAddress,
|
|
2208
|
+
// Echo the credit code through so the server marks it as used
|
|
2209
|
+
// after the on-chain confirm succeeds.
|
|
2210
|
+
promoCode: createResult.promoCode
|
|
2191
2211
|
});
|
|
2192
2212
|
console.log("[useCreateGame] Step 3 done.");
|
|
2193
2213
|
const result = {
|
|
@@ -2204,14 +2224,14 @@ function useCreateGame() {
|
|
|
2204
2224
|
const home = event?.opponents?.[0]?.name ?? null;
|
|
2205
2225
|
const away = event?.opponents?.[1]?.name ?? null;
|
|
2206
2226
|
const teamLabel = params.teamChoice === "home" ? teamNickname(home) : params.teamChoice === "away" ? teamNickname(away) : "Draw";
|
|
2207
|
-
const message = `I just placed a ${
|
|
2227
|
+
const message = `I just placed a ${wagerAmount} SOL bet on ${teamLabel} - Join me!`;
|
|
2208
2228
|
const gameInvite = {
|
|
2209
2229
|
gameId: createResult.gameId,
|
|
2210
2230
|
gameAddress: createResult.gameAddress,
|
|
2211
2231
|
title: event?.title,
|
|
2212
2232
|
league: event?.league,
|
|
2213
2233
|
gameType: "sports",
|
|
2214
|
-
buyIn:
|
|
2234
|
+
buyIn: wagerAmount,
|
|
2215
2235
|
status: "waiting",
|
|
2216
2236
|
homeTeam: home,
|
|
2217
2237
|
awayTeam: away,
|
|
@@ -6100,7 +6120,7 @@ function JoinGameSheet({
|
|
|
6100
6120
|
const [showSuccess, setShowSuccess] = (0, import_react41.useState)(false);
|
|
6101
6121
|
const [useCredit, setUseCredit] = (0, import_react41.useState)(false);
|
|
6102
6122
|
const oldestCredit = credits.length > 0 ? credits[0] : null;
|
|
6103
|
-
const canUseCredit = !!oldestCredit && oldestCredit.amountSOL >= game.buyIn;
|
|
6123
|
+
const canUseCredit = !!oldestCredit && Math.round(oldestCredit.amountSOL * 1e9) >= Math.round(game.buyIn * 1e9);
|
|
6104
6124
|
const overlayOpacity = (0, import_react41.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
6105
6125
|
const successScale = (0, import_react41.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
6106
6126
|
const successOpacity = (0, import_react41.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
@@ -7612,9 +7632,13 @@ function CreateGameSheet({
|
|
|
7612
7632
|
const t = useDubsTheme();
|
|
7613
7633
|
const { wallet } = useDubs();
|
|
7614
7634
|
const mutation = useCreateGame();
|
|
7635
|
+
const { credits, refetch: refetchCredits } = useCredits();
|
|
7615
7636
|
const [selectedTeam, setSelectedTeam] = (0, import_react46.useState)(null);
|
|
7616
7637
|
const [wager, setWager] = (0, import_react46.useState)(0.01);
|
|
7617
7638
|
const [showSuccess, setShowSuccess] = (0, import_react46.useState)(false);
|
|
7639
|
+
const [useCredit, setUseCredit] = (0, import_react46.useState)(false);
|
|
7640
|
+
const oldestCredit = credits.length > 0 ? credits[0] : null;
|
|
7641
|
+
const canUseCredit = !!oldestCredit;
|
|
7618
7642
|
const overlayOpacity = (0, import_react46.useRef)(new import_react_native26.Animated.Value(0)).current;
|
|
7619
7643
|
const successScale = (0, import_react46.useRef)(new import_react_native26.Animated.Value(0)).current;
|
|
7620
7644
|
const successOpacity = (0, import_react46.useRef)(new import_react_native26.Animated.Value(0)).current;
|
|
@@ -7669,11 +7693,16 @@ function CreateGameSheet({
|
|
|
7669
7693
|
id: event.id,
|
|
7670
7694
|
playerWallet: wallet.publicKey.toBase58(),
|
|
7671
7695
|
teamChoice: selectedTeam,
|
|
7672
|
-
|
|
7696
|
+
// When sponsoring, the on-chain instruction forces buy-in to
|
|
7697
|
+
// the credit's amount; pass that so client-side wager state
|
|
7698
|
+
// matches what gets recorded.
|
|
7699
|
+
wagerAmount: useCredit && oldestCredit ? oldestCredit.amountSOL : wager,
|
|
7700
|
+
useCredit: useCredit && canUseCredit ? true : void 0
|
|
7673
7701
|
});
|
|
7702
|
+
if (useCredit) refetchCredits();
|
|
7674
7703
|
} catch {
|
|
7675
7704
|
}
|
|
7676
|
-
}, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager]);
|
|
7705
|
+
}, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager, useCredit, oldestCredit, canUseCredit, refetchCredits]);
|
|
7677
7706
|
const statusLabel = STATUS_LABELS6[mutation.status] || "";
|
|
7678
7707
|
const startTime = event.startTime ? new Date(event.startTime) : null;
|
|
7679
7708
|
const timeLabel = startTime ? startTime.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" }) + " at " + startTime.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }) : "TBD";
|
|
@@ -7748,7 +7777,26 @@ function CreateGameSheet({
|
|
|
7748
7777
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native26.Text, { style: [styles20.summaryValue, { color: t.success }], children: "Set the odds" })
|
|
7749
7778
|
] })
|
|
7750
7779
|
] }),
|
|
7751
|
-
selectedTeam && /* @__PURE__ */ (0, import_jsx_runtime23.
|
|
7780
|
+
selectedTeam && canUseCredit && oldestCredit && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7781
|
+
import_react_native26.TouchableOpacity,
|
|
7782
|
+
{
|
|
7783
|
+
style: [styles20.creditRow, { backgroundColor: useCredit ? "#22C55E18" : t.surface, borderColor: useCredit ? "#22C55E" : t.border }],
|
|
7784
|
+
activeOpacity: 0.8,
|
|
7785
|
+
onPress: () => setUseCredit((v) => !v),
|
|
7786
|
+
children: [
|
|
7787
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native26.View, { style: styles20.creditRowText, children: [
|
|
7788
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native26.Text, { style: [styles20.creditTitle, { color: useCredit ? "#22C55E" : t.text }], children: [
|
|
7789
|
+
"\u{1F381} Use my ",
|
|
7790
|
+
formatSol2(oldestCredit.amountSOL),
|
|
7791
|
+
" SOL credit"
|
|
7792
|
+
] }),
|
|
7793
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native26.Text, { style: [styles20.creditSub, { color: t.textMuted }], children: useCredit ? "Treasury covers rent + buy-in" : `${credits.length} credit${credits.length === 1 ? "" : "s"} from your streak` })
|
|
7794
|
+
] }),
|
|
7795
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native26.View, { style: [styles20.creditCheckbox, useCredit && { backgroundColor: "#22C55E", borderColor: "#22C55E" }], children: useCredit && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native26.Text, { style: styles20.creditCheck, children: "\u2713" }) })
|
|
7796
|
+
]
|
|
7797
|
+
}
|
|
7798
|
+
),
|
|
7799
|
+
selectedTeam && !useCredit && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7752
7800
|
SolSlider,
|
|
7753
7801
|
{
|
|
7754
7802
|
value: wager,
|
|
@@ -7802,6 +7850,12 @@ var styles20 = import_react_native26.StyleSheet.create({
|
|
|
7802
7850
|
ctaButton: { marginTop: 16, height: 54, borderRadius: 14, justifyContent: "center", alignItems: "center" },
|
|
7803
7851
|
ctaText: { color: "#FFFFFF", fontSize: 16, fontWeight: "700" },
|
|
7804
7852
|
ctaLoading: { flexDirection: "row", alignItems: "center", gap: 10 },
|
|
7853
|
+
creditRow: { flexDirection: "row", alignItems: "center", gap: 12, marginTop: 12, padding: 12, borderRadius: 12, borderWidth: 1.5 },
|
|
7854
|
+
creditRowText: { flex: 1, gap: 2 },
|
|
7855
|
+
creditTitle: { fontSize: 14, fontWeight: "700" },
|
|
7856
|
+
creditSub: { fontSize: 12, fontWeight: "500" },
|
|
7857
|
+
creditCheckbox: { width: 22, height: 22, borderRadius: 11, borderWidth: 2, borderColor: "#3A3A3C", alignItems: "center", justifyContent: "center" },
|
|
7858
|
+
creditCheck: { color: "#FFFFFF", fontSize: 14, fontWeight: "900" },
|
|
7805
7859
|
successOverlay: { ...import_react_native26.StyleSheet.absoluteFillObject, zIndex: 100, alignItems: "center", justifyContent: "center", backgroundColor: "rgba(0,0,0,0.85)" },
|
|
7806
7860
|
successContent: { alignItems: "center", gap: 12 },
|
|
7807
7861
|
successEmoji: { fontSize: 64 },
|