⚡ Vite
W.I.P
This guide provides a step-by-step walkthrough for integrating Gamba into your Vite.js application.
Installation
First, ensure you have the necessary Gamba packages installed in your project:
npm install gamba-core-v2 gamba-react-v2 gamba-react-ui-v2
Create a .env for rpc url
NEXT_PUBLIC_RPC_ENDPOINT=<HELIUS API KEY>
Setting Up Gamba Providers
In your Vite.js project, update the src/main.tsx
file to include the GambaProvider
and GambaPlatformProvider
. Replace <YOUR_PLATFORM_CREATOR_ADDRESS_HERE>
with your actual creator address.
// src/main.tsx
import "@solana/wallet-adapter-react-ui/styles.css";
import React from "react";
import ReactDOM from "react-dom";
import { GambaPlatformProvider } from "gamba-react-ui-v2";
import { GambaProvider } from "gamba-react-v2";
import { GAMES } from "./games";
import {
ConnectionProvider,
WalletProvider,
} from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import { makeHeliusTokenFetcher } from "gamba-react-ui-v2";
import App from "./App";
const PLATFORM_CREATOR_ADDRESS = "<YOUR_PLATFORM_CREATOR_ADDRESS_HERE>";
const PLATFORM_CREATOR_FEE = "0.005"; // 5% (5/100 = 0.05)
const PLATFORM_JACKPOT_FEE = "0.01"; // 1% (1/100 = 0.01)
const RPC_ENDPOINT =
import.meta.env.NEXT_PUBLIC_RPC_ENDPOINT ??
"https://api.mainnet-beta.solana.com";
ReactDOM.render(
<ConnectionProvider
endpoint={RPC_ENDPOINT}
config={{ commitment: "processed" }}
>
<WalletProvider autoConnect wallets={[]}>
<WalletModalProvider>
<GambaProvider>
<GambaPlatformProvider
creator={PLATFORM_CREATOR_ADDRESS}
games={GAMES}
defaultCreatorFee={PLATFORM_CREATOR_FEE}
defaultJackpotFee={PLATFORM_JACKPOT_FEE}
>
<TokenMetaProvider
// Method that the useTokenMeta will use to fetch token metadata
fetcher={makeHeliusTokenFetcher(RPC_ENDPOINT)}
// List of known tokens that useTokenMeta will fallback to
tokens={[
{
mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
symbol: "USDC",
name: "USD Coin",
image: "/faketoken.png",
decimals: 6,
baseWager: 1e6,
},
{
mint: "So11111111111111111111111111111111111111112",
symbol: "SOL",
name: "Solana",
decimals: 9,
baseWager: 0.01e9,
},
]}
/>
<App />
</GambaPlatformProvider>
</GambaProvider>
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>,
document.getElementById("app")
);
Custom Renderer
Implementing Gamba UI Portals:
The CustomRenderer
is where the bulk of dynamic content management takes place. It utilizes PortalTarget
to render content defined by Portal
, allowing for flexible UI updates in response to various triggers.
Errors and alerts are a critical part of any gaming experience. Implement custom error handling using Gamba UI's Portal
to define error messages that can be dynamically placed across the UI with PortalTarget
.
import { GambaUi, useGambaAudioStore } from "gamba-react-ui-v2";
import React, { useState } from "react";
import { useGamba } from "gamba-react-v2";
export function CustomError() {
return (
<GambaUi.Portal target="error">
<div>
<h1>😭 Oh no!</h1>
<p>Something went wrong</p>
</div>
</GambaUi.Portal>
);
}
export default function CustomRenderer() {
const gamba = useGamba();
const audioStore = useGambaAudioStore();
return (
<>
<div className="game-container">
<GambaUi.PortalTarget target="error" />
<GambaUi.PortalTarget target="screen" />
<div className="absolute left-0 bottom-0 p-1 flex gap-2">
<button
onClick={() =>
audioStore.set((audioStore.masterGain + 0.25) % 1.25)
}
>
Volume: {audioStore.masterGain * 100}%
</button>
</div>
</div>
<div className="controls-container">
<div className="flex-grow flex items-center justify-start gap-2">
<GambaUi.PortalTarget target="controls" />
<GambaUi.PortalTarget target="play" />
</div>
</div>
</>
);
}
Setting Up the Game Component
The game component leverages Gamba UI's Portals
we created in the custom renderer as well as several hooks and components from Gamba UI. The main focus is on handling user wagers and initiating the game.
import { GambaUi, useWagerInput } from "gamba-react-ui-v2";
import React from "react";
export default function ExampleGame() {
const _hue = React.useRef(0);
const [wager, setWager] = useWagerInput();
const game = GambaUi.useGame();
const click = () => {
_hue.current = (_hue.current + 30) % 360;
};
const play = async () => {
await game.play({
wager,
bet: [2, 0],
});
const result = await game.result();
console.log(result);
// Do something with result
};
return (
<>
<GambaUi.Portal target="screen">
<GambaUi.Canvas
render={({ ctx, size }, clock) => {
const scale = 3 + Math.cos(clock.time) * 0.5;
const hue = _hue.current;
ctx.fillStyle = "hsla(" + hue + ", 50%, 3%, 1)";
ctx.fillRect(0, 0, size.width, size.height);
ctx.save();
ctx.translate(size.width / 2, size.height / 2);
for (let i = 0; i < 5; i++) {
ctx.save();
ctx.scale(scale * (1 + i), scale * (1 + i));
ctx.fillStyle = "hsla(" + hue + ", 75%, 60%, .2)";
ctx.beginPath();
ctx.arc(0, 0, 10, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
ctx.fillStyle = "hsla(" + hue + ", 75%, 60%, 1)";
ctx.beginPath();
ctx.arc(0, 0, 8, 0, Math.PI * 2);
ctx.fill();
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "32px Arial";
ctx.fillStyle = "hsla(" + hue + ", 75%, 90%, 1)";
ctx.fillText("HELLO", 0, 0);
ctx.restore();
}}
/>
</GambaUi.Portal>
<GambaUi.Portal target="controls">
<GambaUi.WagerInput value={wager} onChange={setWager} />
<GambaUi.Button onClick={click}>Useless button</GambaUi.Button>
<GambaUi.PlayButton onClick={play}>
Double or Nothing
</GambaUi.PlayButton>
</GambaUi.Portal>
</>
);
}
Create Your Games Configuration
Next, set up your games configuration in src/games/index.tsx
. Here's an example setup for a dice game:
// src/games/index.tsx
import { GameBundle } from "gamba-react-ui-v2";
import dynamic from "next/dynamic";
export const GAMES: GameBundle[] = [
{
id: "example",
meta: {
background: "#ff6490",
name: "Example",
image: "/games/logo.png",
description: `This is a example.`,
},
app: dynamic(() => import("./Example")),
},
// MORE GAMES
];
For further customization and advanced usage, refer to Gamba UI's documentation and explore how you can extend these concepts to fit your specific game development needs.