async function validate(request, verify) {
  if (request.jsonrpc !== '2.0' || typeof request.method !== 'string') {
    throw new Error('Invalid JSON RPC Request');
  }

  if (request.params == undefined || request.params.__signed == undefined) {
    throw new Error('Signed payload missing');
  }

  if (Object.keys(request.params).length !== 1) {
    throw new Error('Invalid request params');
  }

  const signed = request.params.__signed;

  if (signed.account == undefined) {
    throw new Error('Missing account');
  }

  let params;
  try {
    const jsonString = Buffer.from(signed.params, 'base64').toString('utf8');
    params = JSON.parse(jsonString);
  } catch (cause) {
    throw new Error(`Invalid encoded params: ${cause.message}`);
  }

  if (signed.nonce == undefined || typeof signed.nonce !== 'string') {
    throw new Error('Invalid nonce');
  }
  const nonce = Buffer.from(signed.nonce, 'hex');
  if (nonce.length !== 8) {
    throw new Error('Invalid nonce');
  }

  const timestamp = Date.parse(signed.timestamp);
  if (Number.isNaN(timestamp)) {
    throw new Error('Invalid timestamp');
  }

  if (Date.now() - timestamp > 60 * 1000) {
    throw new Error('Signature expired');
  }

  const message = hashMessage(
    signed.timestamp, signed.account, request.method, signed.params, nonce
  );

  try {
    await verify(message, signed.signatures, signed.account);
  } catch (cause) {
    throw new Error(`Verification failed: ${cause.message}`);
  }

  return params;
}
Validate a signed JSON RPC request.
Throws a ValidationError if the request fails validation.

@returns Resolved request params.