Developer Docs

Argus is a permissionless on-chain RSA public key registry for Starknet. Keys from Google, Apple, and Firebase are registered via Reclaim Protocol zkTLS proofs — no admin, no trust.

Contract Addresses

sepolia

Argus0x065a77e8b23a20a804124dc33040b7a0e36c17f34596124caf81f64a27815b56
JWKSRegistry0x0514157c3e910e6b733af913eddf1a38c63ea1e31be338bebc622265218f5bb4

mainnet

Argus0x058b886f831d15a865f6e007f21eb1c77a6a4e943f867e23c5293289c969d101
JWKSRegistry0x04dc4a75126ad6b26eae2e1e5d17f7e5436cfe7a2e168b1326d0ac1704aa563e

Class Hash

Latest declared class hash (Argus):

0x24c091963cb42fdeed6b381d70c90cbdea4730f4fecfb38f5471868fb4236c7

JWKSRegistry ABI (relevant entries)

Use is_key_valid to check whether a JWT kid is registered and active on-chain. Use get_key_if_valid to retrieve the full RSA key struct for signature verification in a single call.

[
  {
    "type": "function",
    "name": "is_key_valid",
    "inputs": [{ "name": "kid", "type": "core::felt252" }],
    "outputs": [{ "type": "core::bool" }],
    "state_mutability": "view"
  },
  {
    "type": "function",
    "name": "get_key",
    "inputs": [{ "name": "kid", "type": "core::felt252" }],
    "outputs": [{ "type": "argus::jwks_registry::JWKSKey" }],
    "state_mutability": "view"
  },
  {
    "type": "function",
    "name": "get_key_if_valid",
    "inputs": [{ "name": "kid", "type": "core::felt252" }],
    "outputs": [{ "type": "argus::jwks_registry::JWKSKey" }],
    "state_mutability": "view"
  }
]

Argus ABI (relevant entries)

register_key is permissionless — any account can submit a Reclaim proof to register a new key. The proof is verified on-chain before writing.

[
  {
    "type": "function",
    "name": "register_key",
    "inputs": [
      { "name": "proof", "type": "argus::argus::Proof" },
      { "name": "kid", "type": "core::felt252" },
      { "name": "key", "type": "argus::jwks_registry::JWKSKey" }
    ],
    "outputs": [],
    "state_mutability": "external"
  },
  {
    "type": "function",
    "name": "get_upgrade_admin",
    "inputs": [],
    "outputs": [{ "type": "core::starknet::contract_address::ContractAddress" }],
    "state_mutability": "view"
  }
]

Reading a Key with starknet.js

Convert the JWT header kid field to a felt252 (UTF-8 big-endian, max 31 bytes), then call is_key_valid on the JWKSRegistry contract.

import { RpcProvider, Contract } from 'starknet';

// Convert a kid string to felt252
function kidToFelt(kid: string): string {
  const bytes = Buffer.from(kid, 'utf8');
  let felt = 0n;
  for (let i = 0; i < Math.min(bytes.length, 31); i++) {
    felt = felt * 256n + BigInt(bytes[i]);
  }
  return '0x' + felt.toString(16);
}

const provider = new RpcProvider({
  nodeUrl: 'https://free-rpc.nethermind.io/mainnet-juno/v0_7',
});

const contract = new Contract(
  [/* minimal ABI with is_key_valid */],
  '0x04dc4a75126ad6b26eae2e1e5d17f7e5436cfe7a2e168b1326d0ac1704aa563e',
  provider,
);

// Check if a Google kid is registered on Mainnet
const kid = 'a3b1...'; // from jwt header
const isValid = await contract.is_key_valid(kidToFelt(kid));
console.log(isValid ? 'Key is active on-chain' : 'Key not registered');

JWKS Endpoints

ProviderJWKS URLOn-chain label
Googlehttps://www.googleapis.com/oauth2/v3/certs0x676f6f676c65
Applehttps://appleid.apple.com/auth/keys0x6170706c65
Firebasehttps://cavos.xyz/.well-known/jwks.json0x6669726562617365

Security Model

Argus verifies every key submission end-to-end on-chain, with no trusted intermediary:

  • Provider identity — verified by Poseidon hash of the JWKS endpoint URL extracted from the Reclaim proof parameters. The URL never changes; only hardcoded endpoints are accepted.
  • kid and RSA modulus n — parsed from the proof context and compared against the submitted key.
  • Montgomery constants — n_prime and r_sq are verified mathematically on-chain, preventing griefing via malformed constants.
  • zkTLS proof — Reclaim Protocol cryptographically attests that the JWKS response was fetched over TLS from the declared URL.

Source Code

The Cairo contracts and this website are open source.

GitHub →