@dubsdotapp/expo 0.5.33 → 0.5.35
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 +64 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +31 -0
- package/src/hooks/useCreateGame.ts +19 -4
- 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,15 @@ 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!`;
|
|
2228
|
+
const strTimestamp = typeof event?.startTime === "string" ? event.startTime.replace(/Z$/, "") : null;
|
|
2208
2229
|
const gameInvite = {
|
|
2209
2230
|
gameId: createResult.gameId,
|
|
2210
2231
|
gameAddress: createResult.gameAddress,
|
|
2211
2232
|
title: event?.title,
|
|
2212
2233
|
league: event?.league,
|
|
2213
2234
|
gameType: "sports",
|
|
2214
|
-
buyIn:
|
|
2235
|
+
buyIn: wagerAmount,
|
|
2215
2236
|
status: "waiting",
|
|
2216
2237
|
homeTeam: home,
|
|
2217
2238
|
awayTeam: away,
|
|
@@ -2220,7 +2241,7 @@ function useCreateGame() {
|
|
|
2220
2241
|
imageUrl: event?.media?.thumbnail ?? null,
|
|
2221
2242
|
strThumb: event?.media?.thumbnail ?? null,
|
|
2222
2243
|
strPoster: event?.media?.poster ?? null,
|
|
2223
|
-
strTimestamp
|
|
2244
|
+
strTimestamp,
|
|
2224
2245
|
creatorTeam: params.teamChoice,
|
|
2225
2246
|
creatorWallet: params.playerWallet
|
|
2226
2247
|
};
|
|
@@ -6100,7 +6121,7 @@ function JoinGameSheet({
|
|
|
6100
6121
|
const [showSuccess, setShowSuccess] = (0, import_react41.useState)(false);
|
|
6101
6122
|
const [useCredit, setUseCredit] = (0, import_react41.useState)(false);
|
|
6102
6123
|
const oldestCredit = credits.length > 0 ? credits[0] : null;
|
|
6103
|
-
const canUseCredit = !!oldestCredit && oldestCredit.amountSOL >= game.buyIn;
|
|
6124
|
+
const canUseCredit = !!oldestCredit && Math.round(oldestCredit.amountSOL * 1e9) >= Math.round(game.buyIn * 1e9);
|
|
6104
6125
|
const overlayOpacity = (0, import_react41.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
6105
6126
|
const successScale = (0, import_react41.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
6106
6127
|
const successOpacity = (0, import_react41.useRef)(new import_react_native21.Animated.Value(0)).current;
|
|
@@ -7612,9 +7633,13 @@ function CreateGameSheet({
|
|
|
7612
7633
|
const t = useDubsTheme();
|
|
7613
7634
|
const { wallet } = useDubs();
|
|
7614
7635
|
const mutation = useCreateGame();
|
|
7636
|
+
const { credits, refetch: refetchCredits } = useCredits();
|
|
7615
7637
|
const [selectedTeam, setSelectedTeam] = (0, import_react46.useState)(null);
|
|
7616
7638
|
const [wager, setWager] = (0, import_react46.useState)(0.01);
|
|
7617
7639
|
const [showSuccess, setShowSuccess] = (0, import_react46.useState)(false);
|
|
7640
|
+
const [useCredit, setUseCredit] = (0, import_react46.useState)(false);
|
|
7641
|
+
const oldestCredit = credits.length > 0 ? credits[0] : null;
|
|
7642
|
+
const canUseCredit = !!oldestCredit;
|
|
7618
7643
|
const overlayOpacity = (0, import_react46.useRef)(new import_react_native26.Animated.Value(0)).current;
|
|
7619
7644
|
const successScale = (0, import_react46.useRef)(new import_react_native26.Animated.Value(0)).current;
|
|
7620
7645
|
const successOpacity = (0, import_react46.useRef)(new import_react_native26.Animated.Value(0)).current;
|
|
@@ -7669,11 +7694,16 @@ function CreateGameSheet({
|
|
|
7669
7694
|
id: event.id,
|
|
7670
7695
|
playerWallet: wallet.publicKey.toBase58(),
|
|
7671
7696
|
teamChoice: selectedTeam,
|
|
7672
|
-
|
|
7697
|
+
// When sponsoring, the on-chain instruction forces buy-in to
|
|
7698
|
+
// the credit's amount; pass that so client-side wager state
|
|
7699
|
+
// matches what gets recorded.
|
|
7700
|
+
wagerAmount: useCredit && oldestCredit ? oldestCredit.amountSOL : wager,
|
|
7701
|
+
useCredit: useCredit && canUseCredit ? true : void 0
|
|
7673
7702
|
});
|
|
7703
|
+
if (useCredit) refetchCredits();
|
|
7674
7704
|
} catch {
|
|
7675
7705
|
}
|
|
7676
|
-
}, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager]);
|
|
7706
|
+
}, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager, useCredit, oldestCredit, canUseCredit, refetchCredits]);
|
|
7677
7707
|
const statusLabel = STATUS_LABELS6[mutation.status] || "";
|
|
7678
7708
|
const startTime = event.startTime ? new Date(event.startTime) : null;
|
|
7679
7709
|
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 +7778,26 @@ function CreateGameSheet({
|
|
|
7748
7778
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native26.Text, { style: [styles20.summaryValue, { color: t.success }], children: "Set the odds" })
|
|
7749
7779
|
] })
|
|
7750
7780
|
] }),
|
|
7751
|
-
selectedTeam && /* @__PURE__ */ (0, import_jsx_runtime23.
|
|
7781
|
+
selectedTeam && canUseCredit && oldestCredit && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7782
|
+
import_react_native26.TouchableOpacity,
|
|
7783
|
+
{
|
|
7784
|
+
style: [styles20.creditRow, { backgroundColor: useCredit ? "#22C55E18" : t.surface, borderColor: useCredit ? "#22C55E" : t.border }],
|
|
7785
|
+
activeOpacity: 0.8,
|
|
7786
|
+
onPress: () => setUseCredit((v) => !v),
|
|
7787
|
+
children: [
|
|
7788
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native26.View, { style: styles20.creditRowText, children: [
|
|
7789
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_native26.Text, { style: [styles20.creditTitle, { color: useCredit ? "#22C55E" : t.text }], children: [
|
|
7790
|
+
"\u{1F381} Use my ",
|
|
7791
|
+
formatSol2(oldestCredit.amountSOL),
|
|
7792
|
+
" SOL credit"
|
|
7793
|
+
] }),
|
|
7794
|
+
/* @__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` })
|
|
7795
|
+
] }),
|
|
7796
|
+
/* @__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" }) })
|
|
7797
|
+
]
|
|
7798
|
+
}
|
|
7799
|
+
),
|
|
7800
|
+
selectedTeam && !useCredit && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7752
7801
|
SolSlider,
|
|
7753
7802
|
{
|
|
7754
7803
|
value: wager,
|
|
@@ -7802,6 +7851,12 @@ var styles20 = import_react_native26.StyleSheet.create({
|
|
|
7802
7851
|
ctaButton: { marginTop: 16, height: 54, borderRadius: 14, justifyContent: "center", alignItems: "center" },
|
|
7803
7852
|
ctaText: { color: "#FFFFFF", fontSize: 16, fontWeight: "700" },
|
|
7804
7853
|
ctaLoading: { flexDirection: "row", alignItems: "center", gap: 10 },
|
|
7854
|
+
creditRow: { flexDirection: "row", alignItems: "center", gap: 12, marginTop: 12, padding: 12, borderRadius: 12, borderWidth: 1.5 },
|
|
7855
|
+
creditRowText: { flex: 1, gap: 2 },
|
|
7856
|
+
creditTitle: { fontSize: 14, fontWeight: "700" },
|
|
7857
|
+
creditSub: { fontSize: 12, fontWeight: "500" },
|
|
7858
|
+
creditCheckbox: { width: 22, height: 22, borderRadius: 11, borderWidth: 2, borderColor: "#3A3A3C", alignItems: "center", justifyContent: "center" },
|
|
7859
|
+
creditCheck: { color: "#FFFFFF", fontSize: 14, fontWeight: "900" },
|
|
7805
7860
|
successOverlay: { ...import_react_native26.StyleSheet.absoluteFillObject, zIndex: 100, alignItems: "center", justifyContent: "center", backgroundColor: "rgba(0,0,0,0.85)" },
|
|
7806
7861
|
successContent: { alignItems: "center", gap: 12 },
|
|
7807
7862
|
successEmoji: { fontSize: 64 },
|