Merge remote-tracking branch 'origin/dev'
This commit is contained in:
commit
818b00dc55
205
package-lock.json
generated
205
package-lock.json
generated
|
|
@ -12,6 +12,7 @@
|
|||
"@coral-xyz/anchor": "^0.31.0",
|
||||
"@fontsource/manrope": "^5.2.5",
|
||||
"@privy-io/react-auth": "^2.7.2",
|
||||
"@solana/spl-token": "^0.4.13",
|
||||
"@solana/web3.js": "^1.98.0",
|
||||
"axios": "^1.8.4",
|
||||
"bs58": "^6.0.0",
|
||||
|
|
@ -2305,6 +2306,193 @@
|
|||
"node": ">=5.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/buffer-layout-utils": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz",
|
||||
"integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@solana/buffer-layout": "^4.0.0",
|
||||
"@solana/web3.js": "^1.32.0",
|
||||
"bigint-buffer": "^1.1.5",
|
||||
"bignumber.js": "^9.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/codecs": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/codecs/-/codecs-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solana/codecs-core": "2.0.0-rc.1",
|
||||
"@solana/codecs-data-structures": "2.0.0-rc.1",
|
||||
"@solana/codecs-numbers": "2.0.0-rc.1",
|
||||
"@solana/codecs-strings": "2.0.0-rc.1",
|
||||
"@solana/options": "2.0.0-rc.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/codecs-core": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solana/errors": "2.0.0-rc.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/codecs-data-structures": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solana/codecs-core": "2.0.0-rc.1",
|
||||
"@solana/codecs-numbers": "2.0.0-rc.1",
|
||||
"@solana/errors": "2.0.0-rc.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/codecs-numbers": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solana/codecs-core": "2.0.0-rc.1",
|
||||
"@solana/errors": "2.0.0-rc.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/codecs-strings": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solana/codecs-core": "2.0.0-rc.1",
|
||||
"@solana/codecs-numbers": "2.0.0-rc.1",
|
||||
"@solana/errors": "2.0.0-rc.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"fastestsmallesttextencoderdecoder": "^1.0.22",
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/errors": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/errors/-/errors-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"errors": "bin/cli.mjs"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/errors/node_modules/chalk": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
|
||||
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/errors/node_modules/commander": {
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/options": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@solana/options/-/options-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@solana/codecs-core": "2.0.0-rc.1",
|
||||
"@solana/codecs-data-structures": "2.0.0-rc.1",
|
||||
"@solana/codecs-numbers": "2.0.0-rc.1",
|
||||
"@solana/codecs-strings": "2.0.0-rc.1",
|
||||
"@solana/errors": "2.0.0-rc.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/spl-token": {
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.4.13.tgz",
|
||||
"integrity": "sha512-cite/pYWQZZVvLbg5lsodSovbetK/eA24gaR0eeUeMuBAMNrT8XFCwaygKy0N2WSg3gSyjjNpIeAGBAKZaY/1w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@solana/buffer-layout": "^4.0.0",
|
||||
"@solana/buffer-layout-utils": "^0.2.0",
|
||||
"@solana/spl-token-group": "^0.0.7",
|
||||
"@solana/spl-token-metadata": "^0.1.6",
|
||||
"buffer": "^6.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@solana/web3.js": "^1.95.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/spl-token-group": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@solana/spl-token-group/-/spl-token-group-0.0.7.tgz",
|
||||
"integrity": "sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@solana/codecs": "2.0.0-rc.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@solana/web3.js": "^1.95.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/spl-token-metadata": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@solana/spl-token-metadata/-/spl-token-metadata-0.1.6.tgz",
|
||||
"integrity": "sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@solana/codecs": "2.0.0-rc.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@solana/web3.js": "^1.95.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@solana/wallet-adapter-base": {
|
||||
"version": "0.9.23",
|
||||
"resolved": "https://registry.npmjs.org/@solana/wallet-adapter-base/-/wallet-adapter-base-0.9.23.tgz",
|
||||
|
|
@ -4309,6 +4497,15 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz",
|
||||
"integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
|
|
@ -6060,6 +6257,13 @@
|
|||
"integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fastestsmallesttextencoderdecoder": {
|
||||
"version": "1.0.22",
|
||||
"resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz",
|
||||
"integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==",
|
||||
"license": "CC0-1.0",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
|
||||
|
|
@ -10034,7 +10238,6 @@
|
|||
"version": "5.8.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
|
||||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
"@coral-xyz/anchor": "^0.31.0",
|
||||
"@fontsource/manrope": "^5.2.5",
|
||||
"@privy-io/react-auth": "^2.7.2",
|
||||
"@solana/spl-token": "^0.4.13",
|
||||
"@solana/web3.js": "^1.98.0",
|
||||
"axios": "^1.8.4",
|
||||
"bs58": "^6.0.0",
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -8,8 +8,11 @@ import { PriceSelection } from "./PriceSelection";
|
|||
import { GameSelection } from "./GameSelection";
|
||||
import { createBet } from "@/shared/solana_helpers";
|
||||
import { Game } from "@/types/Game";
|
||||
import { Currency } from "@/types/Currency";
|
||||
import { getDefaultCurrency } from "@/data/currencies";
|
||||
import { connection, EXPLORER_TX_TEMPLATE } from "@/data/shared";
|
||||
import { CONFIRMATION_THRESHOLD } from "@/shared/constants";
|
||||
|
||||
interface GameModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
|
|
@ -21,6 +24,7 @@ export default function GameModal({ isOpen, onClose }: GameModalProps) {
|
|||
|
||||
const [selectedGame, setSelectedGame] = useState<Game | null>(null);
|
||||
const [selectedPrice, setSelectedPrice] = useState<number | null>(null);
|
||||
const [selectedCurrency, setSelectedCurrency] = useState<Currency>(getDefaultCurrency());
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
|
||||
const [shouldRender, setShouldRender] = useState(isOpen);
|
||||
|
|
@ -64,7 +68,7 @@ export default function GameModal({ isOpen, onClose }: GameModalProps) {
|
|||
toast.loading("Creating Game");
|
||||
try {
|
||||
//const ownerProfile = await fetchUserById(user?.id ?? "");
|
||||
const tx = await createBet(wallet, user?.id ?? "", selectedPrice, selectedGame.id, false);
|
||||
const tx = await createBet(wallet, user?.id ?? "", selectedPrice, selectedGame.id, false, selectedCurrency.tokenAddress);
|
||||
const url = EXPLORER_TX_TEMPLATE.replace("{address}", tx);
|
||||
if (tx.length > 5) {
|
||||
connection.confirmTransaction(tx, CONFIRMATION_THRESHOLD).finally(()=>{
|
||||
|
|
@ -140,6 +144,8 @@ export default function GameModal({ isOpen, onClose }: GameModalProps) {
|
|||
<PriceSelection
|
||||
selectedPrice={selectedPrice}
|
||||
onSelect={setSelectedPrice}
|
||||
selectedCurrency={selectedCurrency}
|
||||
onCurrencySelect={setSelectedCurrency}
|
||||
/>
|
||||
<button
|
||||
className="mt-6 w-full py-2 rounded-xl font-semibold bg-[rgb(248,144,22)] text-black hover:bg-white hover:scale-105"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { ConnectedSolanaWallet, usePrivy, useSolanaWallets } from "@privy-io/rea
|
|||
import { RematchModal } from "./RematchModal";
|
||||
import { API_URL, CLUSTER_URL } from '../data/shared';
|
||||
import { clusterApiUrl } from "@solana/web3.js";
|
||||
import { getCurrencyByMint } from "@/data/currencies";
|
||||
|
||||
export default function HeroSection() {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
|
@ -100,13 +101,15 @@ export default function HeroSection() {
|
|||
setRematchTxError(false);
|
||||
|
||||
try {
|
||||
const currency = getCurrencyByMint(lastActiveBet.currency ?? "SOL");
|
||||
// Step 1: Create new bet
|
||||
const tx = await createBet(
|
||||
solWallet,
|
||||
user?.id ?? "",
|
||||
lastActiveBet.wager,
|
||||
lastActiveBet.id,
|
||||
true
|
||||
true,
|
||||
currency?.tokenAddress ?? "11111111111111111111111111111111"
|
||||
);
|
||||
console.log("Rematch created. Transaction ID:", tx);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
|
|||
import Image from "next/image";
|
||||
import { games } from "../data/games";
|
||||
import { usePrivy, useSolanaWallets } from "@privy-io/react-auth";
|
||||
import { joinBet } from "@/shared/solana_helpers";
|
||||
import { joinBet, getVaultByAddress } from "@/shared/solana_helpers";
|
||||
import { Bet } from "../types/Bet";
|
||||
import { fetchUserById } from "@/shared/data_fetcher";
|
||||
import { toast } from "sonner";
|
||||
|
|
@ -77,14 +77,29 @@ export default function YourGames({ bets }: GameModalProps) {
|
|||
console.log("No user found, showing all bets");
|
||||
}
|
||||
|
||||
// Enrich bets with currency information and owner profiles
|
||||
const enrichedBets = await Promise.all(
|
||||
filteredBets.map(async (bet) => {
|
||||
const ownerProfile = await fetchUserById(bet.owner_id);
|
||||
|
||||
return {
|
||||
...bet,
|
||||
ownerProfile,
|
||||
};
|
||||
|
||||
// Fetch currency information if not already present
|
||||
let enrichedBet = { ...bet, ownerProfile };
|
||||
if (!bet.currency && wallets && wallets.length > 0) {
|
||||
try {
|
||||
const solanaWallet = wallets.find(wallet => wallet.type === "solana");
|
||||
if (solanaWallet) {
|
||||
const vaultBet = await getVaultByAddress(solanaWallet, bet.address);
|
||||
if (vaultBet && vaultBet.currency) {
|
||||
enrichedBet = { ...enrichedBet, currency: vaultBet.currency };
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching currency for bet:", error);
|
||||
enrichedBet = { ...enrichedBet, currency: "SOL" }; // Default fallback
|
||||
}
|
||||
}
|
||||
|
||||
return enrichedBet;
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -149,8 +164,8 @@ export default function YourGames({ bets }: GameModalProps) {
|
|||
</div>
|
||||
|
||||
<div className="flex justify-between text-xs font-mono py-1">
|
||||
<p className="text-white">{bet.wager} SOL</p>
|
||||
<p className="text-white">{(bet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL</p>
|
||||
<p className="text-white">{bet.wager} {bet.currency}</p>
|
||||
<p className="text-white text-right">{(bet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} {bet.currency}</p>
|
||||
</div>
|
||||
|
||||
{bet.ownerProfile && (
|
||||
|
|
@ -248,11 +263,11 @@ export default function YourGames({ bets }: GameModalProps) {
|
|||
)}
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-gray-400">Entry:</span>
|
||||
<span className="font-bold">{selectedBet.wager} SOL</span>
|
||||
<span className="font-bold">{selectedBet.wager} {selectedBet.currency}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-gray-400">Prize:</span>
|
||||
<span className="font-bold">{(selectedBet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} SOL</span>
|
||||
<span className="font-bold">{(selectedBet.wager * 2 * WAGER_PRIZE_MULT).toFixed(3)} {selectedBet.currency}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,27 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { Currency } from "../types/Currency";
|
||||
import { currencies, getDefaultCurrency } from "../data/currencies";
|
||||
import { getTokenBalance } from "../shared/solana_helpers";
|
||||
import { useSolanaWallets } from "@privy-io/react-auth";
|
||||
|
||||
interface PriceSelectionProps {
|
||||
selectedPrice: number | null;
|
||||
onSelect: (price: number) => void;
|
||||
selectedCurrency?: Currency;
|
||||
onCurrencySelect?: (currency: Currency) => void;
|
||||
}
|
||||
|
||||
export function PriceSelection({ selectedPrice, onSelect }: PriceSelectionProps) {
|
||||
const presets = [0.01,0.05, 0.1, 0.2, 0.5, 1.0];
|
||||
export function PriceSelection({
|
||||
selectedPrice,
|
||||
onSelect,
|
||||
selectedCurrency = getDefaultCurrency(),
|
||||
onCurrencySelect
|
||||
}: PriceSelectionProps) {
|
||||
const { wallets } = useSolanaWallets();
|
||||
|
||||
const [inputValue, setInputValue] = useState<string>("");
|
||||
const [balance, setBalance] = useState<number | null>(null);
|
||||
const [isLoadingBalance, setIsLoadingBalance] = useState(false);
|
||||
const MIN_AMOUNT = 0.01;
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -16,6 +30,34 @@ export function PriceSelection({ selectedPrice, onSelect }: PriceSelectionProps)
|
|||
}
|
||||
}, [selectedPrice]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBalance = async () => {
|
||||
if (!wallets || wallets.length === 0) {
|
||||
setBalance(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const solanaWallet = wallets.find(wallet => wallet.type === "solana");
|
||||
if (!solanaWallet) {
|
||||
setBalance(null);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoadingBalance(true);
|
||||
try {
|
||||
const tokenBalance = await getTokenBalance(solanaWallet.address, selectedCurrency);
|
||||
setBalance(tokenBalance);
|
||||
} catch (error) {
|
||||
console.error("Error fetching balance:", error);
|
||||
setBalance(null);
|
||||
} finally {
|
||||
setIsLoadingBalance(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchBalance();
|
||||
}, [wallets, selectedCurrency]);
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setInputValue(value);
|
||||
|
|
@ -30,16 +72,46 @@ export function PriceSelection({ selectedPrice, onSelect }: PriceSelectionProps)
|
|||
setInputValue(value.toString());
|
||||
};
|
||||
|
||||
const handleCurrencyChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const selectedSymbol = e.target.value;
|
||||
const currency = currencies.find(c => c.symbol === selectedSymbol);
|
||||
if (currency && onCurrencySelect) {
|
||||
onCurrencySelect(currency);
|
||||
}
|
||||
};
|
||||
|
||||
const formatBalance = (balance: number | null) => {
|
||||
if (balance === null) return "Loading...";
|
||||
if (balance === 0) return "0";
|
||||
return balance.toFixed(4);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-6 space-y-2">
|
||||
<label className="block text-sm text-gray-300 font-mono mb-1">Select Currency</label>
|
||||
|
||||
<select
|
||||
value={selectedCurrency.symbol}
|
||||
onChange={handleCurrencyChange}
|
||||
className="bg-[rgb(10,10,10)] border border-gray-700 text-[rgb(248,144,22)] font-mono px-2 py-1 rounded-lg w-full cursor-pointer"
|
||||
>
|
||||
<option>SOL</option>
|
||||
{currencies.map((currency) => (
|
||||
<option key={currency.symbol} value={currency.symbol}>
|
||||
{currency.symbol} - {currency.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<label className="block text-sm text-gray-300 font-mono mb-1">Entry Price (SOL)</label>
|
||||
|
||||
<div className="flex items-center justify-between text-sm text-gray-400 font-mono">
|
||||
<span>Wallet Balance:</span>
|
||||
<span className={`${isLoadingBalance ? 'text-gray-500' : 'text-[rgb(248,144,22)]'}`}>
|
||||
{formatBalance(balance)} {selectedCurrency.symbol}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label className="block text-sm text-gray-300 font-mono mb-1">
|
||||
Entry Price ({selectedCurrency.symbol})
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
type="number"
|
||||
|
|
@ -47,7 +119,7 @@ export function PriceSelection({ selectedPrice, onSelect }: PriceSelectionProps)
|
|||
value={inputValue}
|
||||
onChange={handleInputChange}
|
||||
className="bg-[rgb(10,10,10)] border border-gray-700 text-[rgb(248,144,22)] font-mono px-2 py-1 rounded-lg flex-1 appearance-none no-spinner"
|
||||
placeholder="e.g. 0.5"
|
||||
placeholder={`e.g. 0.5`}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
|
|
@ -60,7 +132,7 @@ export function PriceSelection({ selectedPrice, onSelect }: PriceSelectionProps)
|
|||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-1.5 mt-2">
|
||||
{presets.map((price) => (
|
||||
{selectedCurrency.price_presets.map((price: number) => (
|
||||
<button
|
||||
key={price}
|
||||
onClick={() => handlePresetClick(price)}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Image from "next/image";
|
|||
import { games } from "../data/games";
|
||||
import { FiTrash } from "react-icons/fi";
|
||||
import { usePrivy, useSolanaWallets } from "@privy-io/react-auth";
|
||||
import { closeBet } from "@/shared/solana_helpers";
|
||||
import { closeBet, getVaultByAddress } from "@/shared/solana_helpers";
|
||||
import { Bet } from "../types/Bet";
|
||||
import { toast } from "sonner";
|
||||
import { connection, EXPLORER_TX_TEMPLATE } from "@/data/shared";
|
||||
|
|
@ -29,8 +29,35 @@ export default function YourGames({bets}:GameModalProps) {
|
|||
wallet = _wallet;
|
||||
}
|
||||
});
|
||||
setMyBets(bets.filter((bet) => bet.owner === wallet.address));
|
||||
|
||||
|
||||
// Filter bets owned by the current user
|
||||
const userBets = bets.filter((bet) => bet.owner === wallet.address);
|
||||
|
||||
// Enrich bets with currency information
|
||||
const enrichedBets = await Promise.all(
|
||||
userBets.map(async (bet) => {
|
||||
// Fetch currency information if not already present
|
||||
let enrichedBet = { ...bet };
|
||||
if (!bet.currency && wallets && wallets.length > 0) {
|
||||
try {
|
||||
const solanaWallet = wallets.find(wallet => wallet.type === "solana");
|
||||
if (solanaWallet) {
|
||||
const vaultBet = await getVaultByAddress(solanaWallet, bet.address);
|
||||
if (vaultBet && vaultBet.currency) {
|
||||
enrichedBet = { ...enrichedBet, currency: vaultBet.currency };
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching currency for bet:", error);
|
||||
enrichedBet = { ...enrichedBet, currency: "SOL" }; // Default fallback
|
||||
}
|
||||
}
|
||||
|
||||
return enrichedBet;
|
||||
})
|
||||
);
|
||||
|
||||
setMyBets(enrichedBets);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
|
@ -113,7 +140,7 @@ export default function YourGames({bets}:GameModalProps) {
|
|||
<div className="mt-4 px-3 text-left">
|
||||
<h3 className="text-lg font-semibold text-white py-2">{game.name}</h3>
|
||||
<p className="text-xs text-gray-400 font-mono py-1">Entry</p>
|
||||
<p className="text-xs text-white font-mono py-1">{bet.wager} SOL</p>
|
||||
<p className="text-xs text-white font-mono py-1">{bet.wager} {bet.currency}</p>
|
||||
</div>
|
||||
|
||||
{/* Close Button */}
|
||||
|
|
|
|||
43
src/data/currencies.ts
Normal file
43
src/data/currencies.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { Currency } from '../types/Currency';
|
||||
|
||||
const OLD_TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
||||
const NEW_TOKEN_PROGRAM_ID = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
||||
|
||||
export const currencies: Currency[] = [
|
||||
{
|
||||
name: "Solana",
|
||||
symbol: "SOL",
|
||||
tokenAddress: "11111111111111111111111111111111", // Native SOL
|
||||
tokenProgram: NEW_TOKEN_PROGRAM_ID,
|
||||
decimals: 9,
|
||||
price_presets:[0.01, 0.05, 0.1, 0.5, 1]
|
||||
},
|
||||
{
|
||||
name: "Tether USD",
|
||||
symbol: "USDT",
|
||||
tokenAddress: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
|
||||
tokenProgram: OLD_TOKEN_PROGRAM_ID,
|
||||
decimals: 6,
|
||||
price_presets:[0.5, 1, 5, 10, 20]
|
||||
},
|
||||
{
|
||||
name: "DuelFi",
|
||||
symbol: "DUELFI",
|
||||
tokenAddress: "FiQBQdASK3AJVZfE7Nc5KwHvQiTd8YepsHAexopPF1eS",
|
||||
tokenProgram: OLD_TOKEN_PROGRAM_ID,
|
||||
decimals: 9,
|
||||
price_presets:[100, 500, 1000, 5000, 10000]
|
||||
}
|
||||
];
|
||||
|
||||
export const getCurrencyBySymbol = (symbol: string): Currency | undefined => {
|
||||
return currencies.find(currency => currency.symbol === symbol);
|
||||
};
|
||||
|
||||
export const getCurrencyByMint = (mint: string): Currency | undefined => {
|
||||
return currencies.find(currency => currency.tokenAddress === mint);
|
||||
};
|
||||
|
||||
export const getDefaultCurrency = (): Currency => {
|
||||
return currencies[0]; // SOL as default
|
||||
};
|
||||
|
|
@ -27,7 +27,7 @@ export const games = [
|
|||
name:"Bubble Blast",
|
||||
entryFee: "0.05 ETH",
|
||||
thumbnail: "/duelfiassets/Bubble Blast Game Cover Illustration.png",
|
||||
isAvailable: false
|
||||
isAvailable: true
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { Connection } from "@solana/web3.js";
|
||||
import { clusterApiUrl, Connection } from "@solana/web3.js";
|
||||
|
||||
// Replace this URL with your dedicated RPC endpoint
|
||||
// You can get one from providers like QuickNode, Alchemy, Helius, or GenesysGo
|
||||
// export const CLUSTER_URL = "https://tiniest-cold-darkness.solana-mainnet.quiknode.pro/72332d636ff78d498b880bd8fdc3eb646c827da8/";
|
||||
// export const CLUSTER_URL = "https://go.getblock.io/908837801b534ae7a6f0869fc44cc567";
|
||||
export const CLUSTER_URL = "https://solana-mainnet.core.chainstack.com/c54e14eef17693283a0323efcc4ce731";
|
||||
export const CLUSTER_URL_DEV= clusterApiUrl("devnet");
|
||||
// export const CLUSTER_URL = "https://mainnet.helius-rpc.com/?api-key=72332d63-6ff7-4d49-8b88-0bd8fdc3eb64";
|
||||
// export const CLUSTER_URL = clusterApiUrl("devnet");
|
||||
export const EXPLORER_ADDRESS_TEMPLATE = "https://explorer.solana.com/address/{address}";
|
||||
|
|
@ -16,3 +17,6 @@ export const API_BASE_URL = "/api/";
|
|||
export const VALIDATOR_URL = "https://validator.duelfi.io/";
|
||||
export const VALIDATOR_URL_DEV = "https://validatordev.duelfi.io/";
|
||||
|
||||
|
||||
export const TOKEN_PROGRAM_ID = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
||||
export const TOKEN_PROGRAM_ID_OLD = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
||||
|
|
|
|||
940
src/idl/bets.ts
940
src/idl/bets.ts
|
|
@ -28,7 +28,25 @@ export type Bets = {
|
|||
"accounts": [
|
||||
{
|
||||
"name": "betsList",
|
||||
"writable": true
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
115,
|
||||
95,
|
||||
108,
|
||||
105,
|
||||
115,
|
||||
116
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
|
|
@ -84,6 +102,218 @@ export type Bets = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "closeBetToken",
|
||||
"discriminator": [
|
||||
253,
|
||||
179,
|
||||
157,
|
||||
65,
|
||||
93,
|
||||
13,
|
||||
142,
|
||||
130
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "betsList",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "betVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
95,
|
||||
118,
|
||||
97,
|
||||
117,
|
||||
108,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "owner"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "gameId"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "nonce"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "winner",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "tokenMint"
|
||||
},
|
||||
{
|
||||
"name": "tokenVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "betVault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "winnerTokenAccount",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "winner"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"name": "associatedTokenProgram",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "winner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "userid",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "gameId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "createBet",
|
||||
"discriminator": [
|
||||
|
|
@ -164,6 +394,210 @@ export type Bets = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "createBetToken",
|
||||
"discriminator": [
|
||||
112,
|
||||
150,
|
||||
197,
|
||||
85,
|
||||
168,
|
||||
49,
|
||||
140,
|
||||
199
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "tokenMint"
|
||||
},
|
||||
{
|
||||
"name": "betsList",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "betVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
95,
|
||||
118,
|
||||
97,
|
||||
117,
|
||||
108,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "payer"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "gameId"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "nonce"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "payerTokenAccount",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "payer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tokenVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "betVault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"name": "associatedTokenProgram",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "wager",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "gameId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deductFees",
|
||||
"discriminator": [
|
||||
|
|
@ -218,6 +652,340 @@ export type Bets = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deductFeesToken",
|
||||
"discriminator": [
|
||||
92,
|
||||
93,
|
||||
60,
|
||||
121,
|
||||
30,
|
||||
164,
|
||||
148,
|
||||
135
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "betsList",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "betVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
95,
|
||||
118,
|
||||
97,
|
||||
117,
|
||||
108,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "owner"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "gameId"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "nonce"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "feeWallet",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "ownerReferrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "joinerReferrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "tokenMint"
|
||||
},
|
||||
{
|
||||
"name": "tokenVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "betVault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "feeWalletTokenAccount",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "feeWallet"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ownerReferrerTokenAccount",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "ownerReferrer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "joinerReferrerTokenAccount",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "joinerReferrer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"name": "associatedTokenProgram",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "winner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "userid",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "gameId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "initialize",
|
||||
"discriminator": [
|
||||
|
|
@ -303,6 +1071,168 @@ export type Bets = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "joinBetToken",
|
||||
"discriminator": [
|
||||
166,
|
||||
253,
|
||||
62,
|
||||
118,
|
||||
163,
|
||||
87,
|
||||
166,
|
||||
204
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "betVault",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "tokenMint"
|
||||
},
|
||||
{
|
||||
"name": "payerTokenAccount",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "payer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tokenVault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "betVault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "tokenMint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram"
|
||||
},
|
||||
{
|
||||
"name": "associatedTokenProgram",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "gameId",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "refundBet",
|
||||
"discriminator": [
|
||||
|
|
@ -387,6 +1317,10 @@ export type Bets = {
|
|||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "gameId",
|
||||
"type": "string"
|
||||
|
|
@ -407,6 +1341,10 @@ export type Bets = {
|
|||
"name": "joinerId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "tokenMint",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "wager",
|
||||
"type": "u64"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,25 @@
|
|||
"accounts": [
|
||||
{
|
||||
"name": "bets_list",
|
||||
"writable": true
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
115,
|
||||
95,
|
||||
108,
|
||||
105,
|
||||
115,
|
||||
116
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
|
|
@ -78,6 +96,218 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "close_bet_token",
|
||||
"discriminator": [
|
||||
253,
|
||||
179,
|
||||
157,
|
||||
65,
|
||||
93,
|
||||
13,
|
||||
142,
|
||||
130
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "bets_list",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "bet_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
95,
|
||||
118,
|
||||
97,
|
||||
117,
|
||||
108,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "owner"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "game_id"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "nonce"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "winner",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "token_mint"
|
||||
},
|
||||
{
|
||||
"name": "token_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "bet_vault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "winner_token_account",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "winner"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "system_program",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "token_program"
|
||||
},
|
||||
{
|
||||
"name": "associated_token_program",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "winner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "userid",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "game_id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "create_bet",
|
||||
"discriminator": [
|
||||
|
|
@ -158,6 +388,210 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "create_bet_token",
|
||||
"discriminator": [
|
||||
112,
|
||||
150,
|
||||
197,
|
||||
85,
|
||||
168,
|
||||
49,
|
||||
140,
|
||||
199
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "token_mint"
|
||||
},
|
||||
{
|
||||
"name": "bets_list",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "bet_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
95,
|
||||
118,
|
||||
97,
|
||||
117,
|
||||
108,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "payer"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "game_id"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "_nonce"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "payer_token_account",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "payer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "token_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "bet_vault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "system_program",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "token_program"
|
||||
},
|
||||
{
|
||||
"name": "associated_token_program",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "wager",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "user_id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "game_id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deduct_fees",
|
||||
"discriminator": [
|
||||
|
|
@ -212,6 +646,340 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deduct_fees_token",
|
||||
"discriminator": [
|
||||
92,
|
||||
93,
|
||||
60,
|
||||
121,
|
||||
30,
|
||||
164,
|
||||
148,
|
||||
135
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "bets_list",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "bet_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [
|
||||
98,
|
||||
101,
|
||||
116,
|
||||
95,
|
||||
118,
|
||||
97,
|
||||
117,
|
||||
108,
|
||||
116
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "owner"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "game_id"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"path": "nonce"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "fee_wallet",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "owner_referrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "joiner_referrer",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "token_mint"
|
||||
},
|
||||
{
|
||||
"name": "token_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "bet_vault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "fee_wallet_token_account",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "fee_wallet"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "owner_referrer_token_account",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "owner_referrer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "joiner_referrer_token_account",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "joiner_referrer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "system_program",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "token_program"
|
||||
},
|
||||
{
|
||||
"name": "associated_token_program",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "winner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "userid",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "game_id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "initialize",
|
||||
"discriminator": [
|
||||
|
|
@ -297,6 +1065,168 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "join_bet_token",
|
||||
"discriminator": [
|
||||
166,
|
||||
253,
|
||||
62,
|
||||
118,
|
||||
163,
|
||||
87,
|
||||
166,
|
||||
204
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "bet_vault",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"writable": true,
|
||||
"signer": true
|
||||
},
|
||||
{
|
||||
"name": "token_mint"
|
||||
},
|
||||
{
|
||||
"name": "payer_token_account",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "payer"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "token_vault",
|
||||
"writable": true,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "bet_vault"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_program"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "token_mint"
|
||||
}
|
||||
],
|
||||
"program": {
|
||||
"kind": "const",
|
||||
"value": [
|
||||
140,
|
||||
151,
|
||||
37,
|
||||
143,
|
||||
78,
|
||||
36,
|
||||
137,
|
||||
241,
|
||||
187,
|
||||
61,
|
||||
16,
|
||||
41,
|
||||
20,
|
||||
142,
|
||||
13,
|
||||
131,
|
||||
11,
|
||||
90,
|
||||
19,
|
||||
153,
|
||||
218,
|
||||
255,
|
||||
16,
|
||||
132,
|
||||
4,
|
||||
142,
|
||||
123,
|
||||
216,
|
||||
219,
|
||||
233,
|
||||
248,
|
||||
89
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "system_program",
|
||||
"address": "11111111111111111111111111111111"
|
||||
},
|
||||
{
|
||||
"name": "token_program"
|
||||
},
|
||||
{
|
||||
"name": "associated_token_program",
|
||||
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "user_id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "game_id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "refund_bet",
|
||||
"discriminator": [
|
||||
|
|
@ -381,6 +1311,10 @@
|
|||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "nonce",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "game_id",
|
||||
"type": "string"
|
||||
|
|
@ -401,6 +1335,10 @@
|
|||
"name": "joiner_id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "token_mint",
|
||||
"type": "pubkey"
|
||||
},
|
||||
{
|
||||
"name": "wager",
|
||||
"type": "u64"
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ export async function showNewGameNotification(username:string, game:string, wage
|
|||
}
|
||||
}
|
||||
|
||||
export async function add_new_activity(type:string, owner_id:string, joiner_id:string, game:string, amount:number ){
|
||||
export async function add_new_activity(type:string, owner_id:string, joiner_id:string, game:string, amount:number, currency_symbol:string ){
|
||||
try{
|
||||
const isDevnet = CLUSTER_URL === clusterApiUrl("devnet");
|
||||
const url = `${API_URL}add_activity.php?type=${type}&owner_id=${owner_id}&joiner_id=${joiner_id}&game=${game}&amount=${amount}&devnet=${isDevnet ? "1" : "0"}`;
|
||||
const url = `${API_URL}add_activity.php?type=${type}&owner_id=${owner_id}&joiner_id=${joiner_id}&game=${game}&amount=${amount}¤cy_symbol=${currency_symbol}&devnet=${isDevnet ? "1" : "0"}`;
|
||||
console.log(url);
|
||||
await fetch(url);
|
||||
}catch(error){
|
||||
|
|
|
|||
|
|
@ -3,11 +3,15 @@ import { Bets } from "@/idl/bets";
|
|||
import { AnchorProvider, BN, Program } from "@coral-xyz/anchor";
|
||||
import { ConnectedSolanaWallet } from "@privy-io/react-auth";
|
||||
import { Connection, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
|
||||
import { getAssociatedTokenAddress } from "@solana/spl-token";
|
||||
import idl from "../idl/bets_idl.json";
|
||||
import { Bet } from "@/types/Bet";
|
||||
import { toast } from "sonner";
|
||||
import { CONFIRMATION_THRESHOLD } from "./constants";
|
||||
import { add_new_activity } from "./data_fetcher";
|
||||
import { Currency } from "@/types/Currency";
|
||||
import { getCurrencyByMint } from "@/data/currencies";
|
||||
|
||||
export async function fetchOpenBets(): Promise<Bet[]> {
|
||||
|
||||
const response = await fetch(`${VALIDATOR_URL}fetchBets`);
|
||||
|
|
@ -42,6 +46,18 @@ export async function getVaultByAddress(wallets: ConnectedSolanaWallet, address:
|
|||
// Extract required bet data
|
||||
const betAcc = await program.account.betVault.fetch(address);
|
||||
// console.log(betAcc.gameId);
|
||||
|
||||
// Determine currency symbol from tokenMint
|
||||
let currencySymbol = "SOL"; // Default to SOL
|
||||
let lamp_per_sol = LAMPORTS_PER_SOL;
|
||||
if (betAcc.tokenMint.toString() !== "So11111111111111111111111111111111111111112") {
|
||||
const currency = getCurrencyByMint(betAcc.tokenMint.toString());
|
||||
if (currency) {
|
||||
currencySymbol = currency.symbol;
|
||||
lamp_per_sol = Math.pow(10, currency.decimals);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
address: address.toString(),
|
||||
id: betAcc.gameId,
|
||||
|
|
@ -49,7 +65,8 @@ export async function getVaultByAddress(wallets: ConnectedSolanaWallet, address:
|
|||
owner_id: betAcc.ownerId,
|
||||
joiner: betAcc.joiner ? betAcc.joiner.toBase58() : "Open",
|
||||
joiner_id: betAcc.joinerId,
|
||||
wager: betAcc.wager.toNumber() / LAMPORTS_PER_SOL
|
||||
wager: betAcc.wager.toNumber() / lamp_per_sol,
|
||||
currency: currencySymbol
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error fetching open bets:", error);
|
||||
|
|
@ -95,14 +112,23 @@ export async function closeBet(wallets: ConnectedSolanaWallet, uid:string, betI
|
|||
|
||||
const winner = new PublicKey(wallets.address);
|
||||
const chosenBetVaultAcc = await program.account.betVault.fetch(chosenBet);
|
||||
|
||||
// Execute the closeBet transaction
|
||||
const tx = await program.methods
|
||||
.closeBet(winner, uid)
|
||||
let txId="";
|
||||
let currency_symbol = "SOL";
|
||||
if(chosenBetVaultAcc.tokenMint.toString() !== "11111111111111111111111111111111"){
|
||||
const currency = getCurrencyByMint(chosenBetVaultAcc.tokenMint.toString());
|
||||
if(!currency){
|
||||
toast.error("Currency not found");
|
||||
return "";
|
||||
}
|
||||
currency_symbol = currency.symbol;
|
||||
const tokenProgramID = new PublicKey(currency.tokenProgram);
|
||||
const tx = await program.methods
|
||||
.closeBetToken(winner, uid, chosenBetVaultAcc.owner, game_id, chosenBetVaultAcc.nonce)
|
||||
.accounts({
|
||||
betVault: chosenBet,
|
||||
betsList: bet_list_pda,
|
||||
winner: winner
|
||||
winner: winner,
|
||||
tokenMint: chosenBetVaultAcc.tokenMint,
|
||||
tokenProgram:tokenProgramID
|
||||
})
|
||||
.transaction();
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
|
|
@ -112,8 +138,27 @@ export async function closeBet(wallets: ConnectedSolanaWallet, uid:string, betI
|
|||
const signedTx = await wallet.signTransaction(tx);
|
||||
|
||||
// Send transaction// Replace with correct RPC endpoint
|
||||
const txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
add_new_activity("close", uid, chosenBetVaultAcc.joinerId, game_id, chosenBetVaultAcc.wager.toNumber() / LAMPORTS_PER_SOL);
|
||||
txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
}else{
|
||||
// Execute the closeBet transaction
|
||||
const tx = await program.methods
|
||||
.closeBet(winner, uid)
|
||||
.accounts({
|
||||
betVault: chosenBet,
|
||||
betsList: bet_list_pda,
|
||||
winner: winner
|
||||
})
|
||||
.transaction();
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
||||
|
||||
// Sign transaction with Privy
|
||||
const signedTx = await wallet.signTransaction(tx);
|
||||
|
||||
// Send transaction// Replace with correct RPC endpoint
|
||||
txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
}
|
||||
add_new_activity("close", uid, chosenBetVaultAcc.joinerId, game_id, chosenBetVaultAcc.wager.toNumber() / LAMPORTS_PER_SOL, currency_symbol);
|
||||
console.log(`Transaction: ${txId}`);
|
||||
return txId;
|
||||
} catch (error) {
|
||||
|
|
@ -122,7 +167,7 @@ export async function closeBet(wallets: ConnectedSolanaWallet, uid:string, betI
|
|||
return "";
|
||||
}
|
||||
|
||||
export async function createBet(wallets: ConnectedSolanaWallet, uid: string, selectedPrice: number, selectedGame: string, get_account_address: boolean): Promise<string> {
|
||||
export async function createBet(wallets: ConnectedSolanaWallet, uid: string, selectedPrice: number, selectedGame: string, get_account_address: boolean, tokenMint: string): Promise<string> {
|
||||
|
||||
const wallet = {
|
||||
publicKey: new PublicKey(wallets.address),
|
||||
|
|
@ -144,8 +189,37 @@ export async function createBet(wallets: ConnectedSolanaWallet, uid: string, sel
|
|||
|
||||
console.log(`bets list : ${bet_list_pda}`);
|
||||
|
||||
// Create transaction
|
||||
const tx = await program.methods
|
||||
const tokenMintPubkey = new PublicKey(tokenMint);
|
||||
let txId = "";
|
||||
let currency_symbol = "SOL";
|
||||
if(tokenMint!== "11111111111111111111111111111111"){
|
||||
const currency = getCurrencyByMint(tokenMint);
|
||||
if(!currency){
|
||||
toast.error("Currency not found");
|
||||
return "";
|
||||
}
|
||||
currency_symbol = currency.symbol;
|
||||
const tokenProgramID = new PublicKey(currency.tokenProgram);
|
||||
|
||||
const tx = await program.methods
|
||||
.createBetToken(new BN(selectedPrice * Math.pow(10, currency.decimals)), uid, selectedGame, new BN(nonce))
|
||||
.accounts({
|
||||
betsList: bet_list_pda,
|
||||
tokenMint: tokenMintPubkey,
|
||||
tokenProgram:tokenProgramID
|
||||
})
|
||||
.transaction(); // Get transaction object instead of RPC call
|
||||
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
||||
|
||||
// Sign transaction with Privy
|
||||
const signedTx = await wallet.signTransaction(tx);
|
||||
|
||||
// Send transaction
|
||||
txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
}else{
|
||||
const tx = await program.methods
|
||||
.createBet(new BN(selectedPrice * 1000000000), uid, selectedGame, new BN(nonce))
|
||||
.accounts({
|
||||
betsList: bet_list_pda,
|
||||
|
|
@ -159,10 +233,13 @@ export async function createBet(wallets: ConnectedSolanaWallet, uid: string, sel
|
|||
const signedTx = await wallet.signTransaction(tx);
|
||||
|
||||
// Send transaction
|
||||
const txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
}
|
||||
// Create transaction
|
||||
|
||||
console.log(`Transaction sent: ${txId}`);
|
||||
console.log(`Transaction confirmed: ${txId}`);
|
||||
add_new_activity("create", uid, "", selectedGame, selectedPrice);
|
||||
add_new_activity("create", uid, "", selectedGame, selectedPrice, currency_symbol);
|
||||
if (get_account_address) {
|
||||
const gameIdBytes = Buffer.from(selectedGame); // selectedGame is a string (game_id)
|
||||
const nonceBytes = new BN(nonce).toArrayLike(Buffer, "le", 8); // _nonce.to_le_bytes()
|
||||
|
|
@ -210,32 +287,57 @@ export async function joinBet(wallets: ConnectedSolanaWallet, uid: string, gameI
|
|||
const program = new Program<Bets>(idl, provider);
|
||||
|
||||
try {
|
||||
const [bet_list_pda] = await PublicKey.findProgramAddress(
|
||||
[Buffer.from("bets_list")],
|
||||
program.programId
|
||||
);
|
||||
const connection = new Connection(CLUSTER_URL, CONFIRMATION_THRESHOLD);
|
||||
const betVaultPubkey = new PublicKey(address);
|
||||
|
||||
console.log(`bets list : ${bet_list_pda}`);
|
||||
|
||||
// Create transaction
|
||||
const tx = await program.methods
|
||||
.joinBet(uid, gameId)
|
||||
.accounts({
|
||||
betVault: betVaultPubkey,
|
||||
})
|
||||
.transaction(); // Get transaction object instead of RPC call
|
||||
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
||||
|
||||
// Sign transaction with Privy
|
||||
const signedTx = await wallet.signTransaction(tx);
|
||||
const chosenBetVaultAcc = await program.account.betVault.fetch(betVaultPubkey);
|
||||
// Send transaction// Replace with correct RPC endpoint
|
||||
const txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
add_new_activity("join", "",uid, gameId, chosenBetVaultAcc.wager.toNumber() / LAMPORTS_PER_SOL);
|
||||
|
||||
let txId = "";
|
||||
let currency_symbol = "SOL";
|
||||
if(chosenBetVaultAcc.tokenMint.toString() !== "11111111111111111111111111111111"){
|
||||
//Token bet
|
||||
// Create transaction
|
||||
const currency = getCurrencyByMint(chosenBetVaultAcc.tokenMint.toString());
|
||||
if(!currency){
|
||||
toast.error("Currency not found");
|
||||
return "";
|
||||
}
|
||||
currency_symbol = currency.symbol;
|
||||
const tokenProgramID = new PublicKey(currency.tokenProgram);
|
||||
const tx = await program.methods
|
||||
.joinBetToken(uid, gameId)
|
||||
.accounts({
|
||||
betVault:betVaultPubkey,
|
||||
tokenMint: chosenBetVaultAcc.tokenMint,
|
||||
tokenProgram:tokenProgramID
|
||||
})
|
||||
.transaction(); // Get transaction object instead of RPC call
|
||||
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
||||
|
||||
// Sign transaction with Privy
|
||||
const signedTx = await wallet.signTransaction(tx);
|
||||
// Send transaction// Replace with correct RPC endpoint
|
||||
txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
}else{
|
||||
const tx = await program.methods
|
||||
.joinBet(uid, gameId)
|
||||
.accounts({
|
||||
betVault: betVaultPubkey,
|
||||
})
|
||||
.transaction(); // Get transaction object instead of RPC call
|
||||
|
||||
tx.feePayer = new PublicKey(wallets.address);
|
||||
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
||||
|
||||
// Sign transaction with Privy
|
||||
const signedTx = await wallet.signTransaction(tx);
|
||||
// Send transaction// Replace with correct RPC endpoint
|
||||
txId = await connection.sendRawTransaction(signedTx.serialize());
|
||||
}
|
||||
|
||||
|
||||
add_new_activity("join", "",uid, gameId, chosenBetVaultAcc.wager.toNumber() / LAMPORTS_PER_SOL, currency_symbol);
|
||||
console.log(`Transaction ID: ${txId}`);
|
||||
return txId;
|
||||
} catch (error: unknown) {
|
||||
|
|
@ -252,4 +354,31 @@ export async function joinBet(wallets: ConnectedSolanaWallet, uid: string, gameI
|
|||
|
||||
function getRandomInt(max: number): number {
|
||||
return Math.floor(Math.random() * max);
|
||||
}
|
||||
|
||||
export async function getTokenBalance(walletAddress: string, currency: Currency): Promise<number> {
|
||||
try {
|
||||
const connection = new Connection(CLUSTER_URL, "confirmed");
|
||||
const publicKey = new PublicKey(walletAddress);
|
||||
|
||||
// For native SOL
|
||||
if (currency.tokenAddress === "So11111111111111111111111111111111111111112") {
|
||||
const balance = await connection.getBalance(publicKey);
|
||||
return balance / Math.pow(10, currency.decimals);
|
||||
}
|
||||
|
||||
// For SPL tokens
|
||||
const tokenMint = new PublicKey(currency.tokenAddress);
|
||||
const tokenAccount = await getAssociatedTokenAddress(tokenMint, publicKey, true, new PublicKey(currency.tokenProgram));
|
||||
console.log(`token vault for ${currency.name}:${walletAddress} : ${tokenAccount}`);
|
||||
try {
|
||||
const tokenBalance = await connection.getTokenAccountBalance(tokenAccount);
|
||||
return tokenBalance.value.uiAmount || 0;
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching token balance:", error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ export interface Bet {
|
|||
joiner: string;
|
||||
joiner_id:string;
|
||||
wager: number;
|
||||
currency?: string; // Currency symbol (SOL, USDT, DUELFI, etc.)
|
||||
ownerProfile?: {
|
||||
id: string;
|
||||
username: string;
|
||||
|
|
|
|||
9
src/types/Currency.ts
Normal file
9
src/types/Currency.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export interface Currency {
|
||||
name: string;
|
||||
symbol: string;
|
||||
tokenAddress: string;
|
||||
decimals: number;
|
||||
price_presets: number[];
|
||||
tokenProgram: string;
|
||||
logo?: string;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user