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
| Argus | 0x065a77e8b23a20a804124dc33040b7a0e36c17f34596124caf81f64a27815b56 |
| JWKSRegistry | 0x0514157c3e910e6b733af913eddf1a38c63ea1e31be338bebc622265218f5bb4 |
mainnet
| Argus | 0x058b886f831d15a865f6e007f21eb1c77a6a4e943f867e23c5293289c969d101 |
| JWKSRegistry | 0x04dc4a75126ad6b26eae2e1e5d17f7e5436cfe7a2e168b1326d0ac1704aa563e |
Class Hash
Latest declared class hash (Argus):
0x24c091963cb42fdeed6b381d70c90cbdea4730f4fecfb38f5471868fb4236c7JWKSRegistry 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
| Provider | JWKS URL | On-chain label |
|---|---|---|
| https://www.googleapis.com/oauth2/v3/certs | 0x676f6f676c65 | |
| Apple | https://appleid.apple.com/auth/keys | 0x6170706c65 |
| Firebase | https://cavos.xyz/.well-known/jwks.json | 0x6669726562617365 |
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.