CRYPTOGRAPHIC ACCESS VERIFIER

Verify Pass & Gate Access

Instantly verify any token ID on the live Arbitrum Stylus contract. Reads isActive(), ownerOf(), and expiryOf() directly from the blockchain.

Live On-Chain Access Checker

Quick Presets:

Gate Any App in 3 Lines

Integrating LiquidPass into your Next.js, Node.js, or Rust application takes less than 2 minutes. Call the deployed Stylus contract view function:

import { createPublicClient, http, parseAbi, zeroAddress } from 'viem';
import { arbitrumSepolia } from 'viem/chains';

const client = createPublicClient({ chain: arbitrumSepolia, transport: http() });
const CORE = '0xac20ef73723e7c620df1024eb04cc0b71fca1055';
const RENTAL = '0x3640ee44A5055ffd5Fd17989fFD95eF478929616';

const core = parseAbi([
  'function ownerOf(uint256) view returns (address)',
  'function isActive(uint256) view returns (bool)',
]);
const rental = parseAbi(['function activeRenter(uint256) view returns (address)']);

// Who holds access to this pass right now, or null if no one does.
export async function accessHolder(tokenId: bigint) {
  const [owner, active] = await Promise.all([
    client.readContract({ address: CORE, abi: core, functionName: 'ownerOf', args: [tokenId] }),
    client.readContract({ address: CORE, abi: core, functionName: 'isActive', args: [tokenId] }),
  ]);
  if (!active) return null;

  // A rented pass is owned by the rental contract, so ownerOf alone is
  // wrong here: access belongs to the renter, and to no one if it is idle.
  if (owner.toLowerCase() === RENTAL.toLowerCase()) {
    const renter = await client.readContract({
      address: RENTAL, abi: rental, functionName: 'activeRenter', args: [tokenId],
    });
    return renter === zeroAddress ? null : renter;
  }
  return owner;
}
Zero Backend Database Required

Access status is resolved cryptographically on Arbitrum Sepolia in under 150ms.