Reading from NEAR testnet…
Reading from NEAR testnet…
CCxG4VeLpJTKpkmtJsPCW723LHhuxk2RodGVqSxS3sPs
darrk.testnet to v1.social08.testnet
set() with 0.1739 NEAR
{
"data": {
"darrk.testnet": {
"widget": {
"nexora-shadowplus-uitest": {
"": "// ==== SETUP: Your contract account here ====\r\nconst CONTRACT = \"darrk.testnet\"; // <-- change to your contract if needed\r\n\r\nfunction nearToN(yocto) {\r\n if (!yocto) return 0;\r\n return Number(yocto) / 1e24;\r\n}\r\nfunction NToYocto(n) {\r\n return (Number(n) * 1e24).toLocaleString(\"fullwide\", { useGrouping: false });\r\n}\r\n\r\nconst accountId = context.accountId;\r\nif (!accountId) return <p>Please sign in with NEAR Wallet</p>;\r\n\r\nconst [status, setStatus] = useState(null);\r\nconst [adminInfo, setAdminInfo] = useState(null);\r\nconst [teamA, setTeamA] = useState([]);\r\nconst [teamB, setTeamB] = useState([]);\r\nconst [userBetA, setUserBetA] = useState(null);\r\nconst [userBetB, setUserBetB] = useState(null);\r\nconst [banList, setBanList] = useState([]);\r\nconst [withdrawInfo, setWithdrawInfo] = useState(null);\r\nconst [throwInfo, setThrowInfo] = useState(null);\r\n\r\nconst [bet, setBet] = useState({ team: \"A\", amount: \"\" });\r\nconst [banUser, setBanUser] = useState(\"\");\r\nconst [unbanUser, setUnbanUser] = useState(\"\");\r\nconst [gameParams, setGameParams] = useState({\r\n potSize: \"\",\r\n commissionRate: \"\",\r\n gameDuration: \"\",\r\n});\r\nconst [throwPct, setThrowPct] = useState(\"\");\r\n\r\nconst [showTeamA, setShowTeamA] = useState(false);\r\nconst [showTeamB, setShowTeamB] = useState(false);\r\nconst [showBanned, setShowBanned] = useState(false);\r\n\r\nconst [loading, setLoading] = useState(false);\r\nconst [toast, setToast] = useState(null);\r\nfunction notify(msg, color) {\r\n setToast({ msg, color });\r\n setTimeout(() => setToast(null), 2500);\r\n}\r\n\r\nconst fetchAll = () => {\r\n setLoading(true);\r\n Promise.all([\r\n Near.asyncView(CONTRACT, \"get_game_status\", {}),\r\n Near.asyncView(CONTRACT, \"get_admin_info\", {}),\r\n Near.asyncView(CONTRACT, \"get_team_bets\", { team: \"A\" }),\r\n Near.asyncView(CONTRACT, \"get_team_bets\", { team: \"B\" }),\r\n Near.asyncView(CONTRACT, \"get_user_bet\", { user_id: accountId, team: \"A\" }),\r\n Near.asyncView(CONTRACT, \"get_user_bet\", { user_id: accountId, team: \"B\" }),\r\n Near.asyncView(CONTRACT, \"get_banned_players\", {}),\r\n Near.asyncView(CONTRACT, \"get_game_status\", {}),\r\n Near.asyncView(CONTRACT, \"can_throw_points\", { user_id: accountId }),\r\n ]).then(\r\n ([\r\n status,\r\n adminInfo,\r\n teamA,\r\n teamB,\r\n userBetA,\r\n userBetB,\r\n banList,\r\n statAgain,\r\n throwInfo,\r\n ]) => {\r\n setStatus(status);\r\n setAdminInfo(adminInfo);\r\n setTeamA(teamA ? Object.entries(teamA) : []);\r\n setTeamB(teamB ? Object.entries(teamB) : []);\r\n setUserBetA(userBetA);\r\n setUserBetB(userBetB);\r\n setBanList(banList || []);\r\n setWithdrawInfo(\r\n statAgain && statAgain.withdrawable\r\n ? statAgain.withdrawable[accountId]\r\n : null\r\n );\r\n setThrowInfo(throwInfo);\r\n setLoading(false);\r\n }\r\n );\r\n};\r\n\r\nuseEffect(() => {\r\n fetchAll();\r\n const i = setInterval(fetchAll, 10000); // auto-refresh every 10s\r\n return () => clearInterval(i);\r\n}, [accountId]);\r\n\r\nconst isAdmin = adminInfo && adminInfo.admin === accountId;\r\nconst btn = (label, onClick, opts) => (\r\n <button {...opts} onClick={onClick}>\r\n {label}\r\n </button>\r\n);\r\n\r\nreturn (\r\n <div\r\n style={{\r\n maxWidth: 520,\r\n margin: \"0 auto\",\r\n padding: 16,\r\n fontFamily: \"sans-serif\",\r\n position: \"relative\",\r\n }}\r\n >\r\n <h2>Team Betting DApp UI</h2>\r\n {toast && (\r\n <div\r\n style={{\r\n position: \"fixed\",\r\n top: \"24px\",\r\n left: 0,\r\n right: 0,\r\n margin: \"auto\",\r\n zIndex: 99,\r\n width: \"280px\",\r\n borderRadius: 7,\r\n padding: 12,\r\n background: toast.color || \"#169\",\r\n color: \"white\",\r\n fontWeight: 600,\r\n textAlign: \"center\",\r\n }}\r\n >\r\n {toast.msg}\r\n </div>\r\n )}\r\n {loading && (\r\n <div\r\n style={{\r\n position: \"absolute\",\r\n left: 0,\r\n right: 0,\r\n top: 60,\r\n margin: \"auto\",\r\n width: 50,\r\n zIndex: 98,\r\n color: \"#999\",\r\n }}\r\n >\r\n ⏳\r\n </div>\r\n )}\r\n <b>Game status:</b>\r\n <div\r\n style={{\r\n fontSize: 13,\r\n background: \"#eee\",\r\n borderRadius: 4,\r\n padding: 8,\r\n marginBottom: 10,\r\n }}\r\n >\r\n {status ? (\r\n <>\r\n <div>\r\n Status: <b>{status.active ? \"Active\" : \"Inactive\"}</b>\r\n </div>\r\n <div>\r\n Started: <b>{status.started ? \"Yes\" : \"No\"}</b>\r\n </div>\r\n <div>\r\n Paused: <b>{status.paused ? \"Yes\" : \"No\"}</b>\r\n </div>\r\n <div>Pot size: {status.pot_size} NEAR</div>\r\n <div>Commission: {status.commission_rate}%</div>\r\n <div>Duration: {status.game_duration} sec</div>\r\n <div>\r\n Team A: {status.team_a_points} pts (\r\n {nearToN(status.team_a_total_amount)} N)\r\n </div>\r\n <div>\r\n Team B: {status.team_b_points} pts (\r\n {nearToN(status.team_b_total_amount)} N)\r\n </div>\r\n <div>\r\n Winning team: <b>{status.winning_team || \"(pending)\"}</b>\r\n </div>\r\n </>\r\n ) : (\r\n \"Loading...\"\r\n )}\r\n </div>\r\n <hr style={{ margin: \"16px 0\" }} />\r\n\r\n <h4>Your bets</h4>\r\n <div>\r\n Team A:{\" \"}\r\n {userBetA && userBetA.amount\r\n ? `${nearToN(userBetA.amount)} N, ${userBetA.points} pts`\r\n : \"None\"}\r\n <br />\r\n Team B:{\" \"}\r\n {userBetB && userBetB.amount\r\n ? `${nearToN(userBetB.amount)} N, ${userBetB.points} pts`\r\n : \"None\"}\r\n </div>\r\n\r\n {/* Throw Points Section */}\r\n {status && status.game_started && throwInfo && (\r\n <div style={{ margin: \"16px 0\" }}>\r\n <h4>Throw Points</h4>\r\n {throwInfo.can_throw ? (\r\n <>\r\n <div style={{ fontSize: 13, marginBottom: 8 }}>\r\n {throwInfo.reason}\r\n </div>\r\n <input\r\n type=\"number\"\r\n placeholder=\"Percent\"\r\n style={{ width: 80 }}\r\n value={throwPct}\r\n onChange={(e) => setThrowPct(e.target.value)}\r\n />\r\n {btn(\r\n \"Throw Points\",\r\n () => {\r\n setLoading(true);\r\n Near.call(\r\n CONTRACT,\r\n \"throw_points\",\r\n { percent: Number(throwPct) },\r\n 100_000_000_000_000,\r\n 0\r\n )\r\n .then(() => notify(\"Points thrown!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\"));\r\n },\r\n { disabled: !throwPct }\r\n )}\r\n </>\r\n ) : (\r\n <div style={{ fontSize: 13, color: \"#666\" }}>\r\n Cannot throw points: {throwInfo.reason}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n <h4>Place bet</h4>\r\n <select\r\n value={bet.team}\r\n onChange={(e) => setBet({ ...bet, team: e.target.value })}\r\n >\r\n <option value=\"A\">Team A</option>\r\n <option value=\"B\">Team B</option>\r\n </select>\r\n <input\r\n style={{ marginLeft: 4, width: 70 }}\r\n placeholder=\"NEAR\"\r\n type=\"number\"\r\n min=\"0.5\"\r\n value={bet.amount}\r\n onChange={(e) => setBet({ ...bet, amount: e.target.value })}\r\n />\r\n {btn(\r\n \"Bet\",\r\n () => {\r\n setLoading(true);\r\n Near.call(\r\n CONTRACT,\r\n \"bet_on_team\",\r\n { team: bet.team },\r\n 150_000_000_000_000,\r\n NToYocto(bet.amount)\r\n )\r\n .then(() => notify(\"Bet sent!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\"));\r\n },\r\n { disabled: !bet.amount || isNaN(bet.amount) }\r\n )}\r\n <div style={{ fontSize: 12, color: \"#aaa\" }}>\r\n Minimum: 0.5 NEAR. Early bird bonus if timer not started!\r\n </div>\r\n <div style={{ margin: \"16px 0\" }}>\r\n <b>Your withdrawable balance: </b>\r\n {withdrawInfo && withdrawInfo > 0\r\n ? `${nearToN(withdrawInfo)} NEAR`\r\n : \"None\"}\r\n {btn(\r\n \"Withdraw\",\r\n () => {\r\n setLoading(true);\r\n Near.call(CONTRACT, \"withdraw\", {}, 100_000_000_000_000, 0)\r\n .then(() => notify(\"Withdrawal requested!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\"));\r\n },\r\n {\r\n style: { marginLeft: 8 },\r\n disabled: !withdrawInfo || withdrawInfo <= 0,\r\n }\r\n )}\r\n </div>\r\n\r\n <div style={{ marginTop: 8 }}>\r\n {btn((showTeamA ? \"Hide\" : \"Show\") + \" Team A bets\", () =>\r\n setShowTeamA(!showTeamA)\r\n )}\r\n {showTeamA && (\r\n <div\r\n style={{\r\n fontSize: 13,\r\n margin: \"6px 0 8px 16px\",\r\n background: \"#f8f8f8\",\r\n borderRadius: 4,\r\n padding: 8,\r\n }}\r\n >\r\n {teamA && teamA.length > 0 ? (\r\n teamA.map(([uid, bet]) => (\r\n <div key={uid}>\r\n {uid}: {nearToN(bet.amount)}N, {bet.points} pts\r\n </div>\r\n ))\r\n ) : (\r\n <div>No bets</div>\r\n )}\r\n </div>\r\n )}\r\n {btn(\r\n (showTeamB ? \"Hide\" : \"Show\") + \" Team B bets\",\r\n () => setShowTeamB(!showTeamB),\r\n { style: { marginLeft: 10 } }\r\n )}\r\n {showTeamB && (\r\n <div\r\n style={{\r\n fontSize: 13,\r\n margin: \"6px 0 8px 16px\",\r\n background: \"#f8f8f8\",\r\n borderRadius: 4,\r\n padding: 8,\r\n }}\r\n >\r\n {teamB && teamB.length > 0 ? (\r\n teamB.map(([uid, bet]) => (\r\n <div key={uid}>\r\n {uid}: {nearToN(bet.amount)}N, {bet.points} pts\r\n </div>\r\n ))\r\n ) : (\r\n <div>No bets</div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n <div style={{ marginTop: 10 }}>\r\n {btn(\r\n (showBanned ? \"Hide\" : \"Show\") +\r\n ` Banned players (${(banList || []).length})`,\r\n () => setShowBanned(!showBanned)\r\n )}\r\n {showBanned && (\r\n <ul>\r\n {(banList || []).map((uid) => (\r\n <li key={uid}>{uid}</li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n\r\n {/* ========== ADMIN CONTROLS ========== */}\r\n {isAdmin && (\r\n <div\r\n style={{\r\n border: \"1px solid #eee\",\r\n background: \"#fafafa\",\r\n borderRadius: 8,\r\n padding: 10,\r\n margin: \"18px 0\",\r\n }}\r\n >\r\n <h3>Admin panel</h3>\r\n <b>Game Controls:</b>\r\n <div style={{ marginBottom: 8 }}>\r\n <div>\r\n <input\r\n placeholder=\"Pot size (NEAR)\"\r\n type=\"number\"\r\n style={{ width: 80 }}\r\n value={gameParams.potSize}\r\n onChange={(e) =>\r\n setGameParams({ ...gameParams, potSize: e.target.value })\r\n }\r\n />\r\n <input\r\n placeholder=\"Commission %\"\r\n type=\"number\"\r\n style={{ width: 60, marginLeft: 8 }}\r\n value={gameParams.commissionRate}\r\n onChange={(e) =>\r\n setGameParams({ ...gameParams, commissionRate: e.target.value })\r\n }\r\n />\r\n <input\r\n placeholder=\"Duration (sec)\"\r\n type=\"number\"\r\n style={{ width: 80, marginLeft: 8 }}\r\n value={gameParams.gameDuration}\r\n onChange={(e) =>\r\n setGameParams({ ...gameParams, gameDuration: e.target.value })\r\n }\r\n />\r\n </div>\r\n {btn(\r\n \"Start Game\",\r\n () =>\r\n Near.call(\r\n CONTRACT,\r\n \"start_game\",\r\n {\r\n pot_size: Number(gameParams.potSize),\r\n game_duration: Number(gameParams.gameDuration),\r\n commission_rate: Number(gameParams.commissionRate),\r\n },\r\n 100_000_000_000_000,\r\n 0\r\n )\r\n .then(() => notify(\"Game started!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n {\r\n disabled:\r\n !gameParams.potSize ||\r\n !gameParams.gameDuration ||\r\n !gameParams.commissionRate,\r\n }\r\n )}\r\n </div>\r\n <div style={{ marginTop: 6, marginBottom: 8 }}>\r\n {btn(\r\n \"Start timer\",\r\n () =>\r\n Near.call(CONTRACT, \"start_timer\", {}, 80_000_000_000_000, 0)\r\n .then(() => notify(\"Timer started!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n { style: { marginLeft: 8 } }\r\n )}\r\n {btn(\r\n \"Pause\",\r\n () =>\r\n Near.call(CONTRACT, \"pause_game\", {}, 60_000_000_000_000, 0)\r\n .then(() => notify(\"Game paused!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n { style: { marginLeft: 8 } }\r\n )}\r\n {btn(\r\n \"Unpause\",\r\n () =>\r\n Near.call(CONTRACT, \"unpause_game\", {}, 60_000_000_000_000, 0)\r\n .then(() => notify(\"Game unpaused!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n { style: { marginLeft: 8 } }\r\n )}\r\n </div>\r\n <div style={{ marginTop: 6, marginBottom: 8 }}>\r\n {btn(\"Force refund/end\", () =>\r\n Near.call(\r\n CONTRACT,\r\n \"force_end_game_refund\",\r\n {},\r\n 150_000_000_000_000,\r\n 0\r\n )\r\n .then(() => notify(\"Force refund done!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\"))\r\n )}\r\n {btn(\r\n \"End game\",\r\n () =>\r\n Near.call(CONTRACT, \"end_game\", {}, 100_000_000_000_000, 0)\r\n .then(() => notify(\"Ended!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n { style: { marginLeft: 8 } }\r\n )}\r\n </div>\r\n <b>Ban Tools:</b>\r\n <div style={{ marginTop: 8 }}>\r\n Ban:{\" \"}\r\n <input\r\n type=\"text\"\r\n style={{ width: 160 }}\r\n value={banUser}\r\n onChange={(e) => setBanUser(e.target.value)}\r\n />\r\n {btn(\r\n \"Ban\",\r\n () =>\r\n Near.call(\r\n CONTRACT,\r\n \"ban_player\",\r\n { player_id: banUser },\r\n 60_000_000_000_000,\r\n 0\r\n )\r\n .then(() => notify(\"Banned!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n { disabled: !banUser }\r\n )}\r\n </div>\r\n <div style={{ marginTop: 2 }}>\r\n Unban:{\" \"}\r\n <input\r\n type=\"text\"\r\n style={{ width: 160 }}\r\n value={unbanUser}\r\n onChange={(e) => setUnbanUser(e.target.value)}\r\n />\r\n {btn(\r\n \"Unban\",\r\n () =>\r\n Near.call(\r\n CONTRACT,\r\n \"unban_player\",\r\n { player_id: unbanUser },\r\n 60_000_000_000_000,\r\n 0\r\n )\r\n .then(() => notify(\"Unbanned!\", \"#19a966\"))\r\n .catch((e) => notify(\"Error: \" + e.message, \"#c33\")),\r\n { disabled: !unbanUser }\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n <div style={{ marginTop: 16, fontSize: 11, color: \"#888\" }}>\r\n All interactions on-chain, powered by NEAR Social.\r\n <br />\r\n <span style={{ fontSize: 10 }}>Auto refreshes every 10s.</span>\r\n </div>\r\n </div>\r\n);\r\n",
"metadata": {
"image": {}
}
}
}
}
}
}1 automatic refund step from the network not shown.
This page reads FastNEAR's public transaction index and stores nothing. This command asks a NEAR archival node for the same transaction and needs no keys.
curl -s https://archival-rpc.testnet.fastnear.com -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tx","params":{"tx_hash":"CCxG4VeLpJTKpkmtJsPCW723LHhuxk2RodGVqSxS3sPs","sender_account_id":"darrk.testnet","wait_until":"FINAL"}}'Vouch has its own page because testnet.nearblocks.io stopped indexing on 27 Sep 2026, so it can't show newer transactions.