<div class="container text-white mx-auto w-full max-w-xl mt-10 p-4 rounded-2xl">
  <h1 class="text-2xl text-center font-bold mb-6">Cases.gg Case/Chest Verifier</h1>
  
  <label for="serverSeed">Server Seed</label>
  <input id="serverSeed" type='text' class='w-full py-2 px-3 rounded-xl mt-1 mb-2' />

  <label for="serverHash">Server Hash</label>
  <input id="serverHash" type='text' class='w-full py-2 px-3 rounded-xl mt-1 mb-2' />

  <label for="clientSeed">Client Seed</label>
  <input id="clientSeed" type='text' class='w-full py-2 px-3 rounded-xl mt-1 mb-2' />
  
  <label for="nonce">Nonce</label>
  <input type="number" id="nonce" name="nonceStart" value="1" class='w-full py-2 px-3 rounded-xl mt-1 mb-2'/>
  
  <label for="rounds">Number of cases</label>
  <input id="rounds" type='number' min='0' max='5' class='w-full py-2 px-3 rounded-xl mt-1 mb-2' value='1' />
  
  <div id="verify" class='bg-blue-600 hover:bg-blue-500 cursor-pointer text-center p-3 rounded-xl mt-3'>
     Verify Game
  </div>
  
  <div id="result" class='my-6'>
  </div>
</div>
body, input {
  background: #2a2e31;
}

.container {
  background: #25282b;
}

label {
  color: #aaa;
}
/* global CryptoJS */

import seedrandom from 'https://cdn.skypack.dev/seedrandom@3.0.5'

const result = document.getElementById('result')

const error = message => {
  result.innerHTML = `<div class="text-red-500">${message}</div>`
}

document.getElementById('verify').onclick = () => {
  const serverSeed = document.getElementById('serverSeed').value
  const serverHash = document.getElementById('serverHash').value
  const clientSeed = document.getElementById('clientSeed').value
  const nonce = document.getElementById('nonce').value
  const rounds = Number(document.getElementById('rounds').value)

  if (!serverSeed) return error('Server seed is required')
  if (!serverHash) return error('Server hash is required')
  if (!clientSeed) return error('Client seed is required')
  if (!rounds || rounds < 1) return error('Number of rounds is required')

  const isHashValid = CryptoJS.SHA256(serverSeed.trim()).toString() === serverHash.trim()

  let results = ''
  for (let i = 1; i <= rounds; i++) {
    const rollNumber = seedrandom(`${serverSeed.trim()}:${clientSeed.trim()}:${nonce.trim()}:${i}`)()
    const ticket = Math.floor(rollNumber * 100_000)
    results += `<div class="text-gray-300">Round ${i} - ${ticket}</div>`
  }

  result.innerHTML = `<div class="text-center">
    <div class="font-bold my-2 uppercase text-xl">
      ${isHashValid
        ? '<div class="text-green-500">Game is valid</div>'
        : '<div class="text-red-500">Game is invalid</div>'}
    </div>

      ${results}
  </div>`
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js