Wallet-auth integration
The current browser integration contract is wallet authentication v1. It gives an application a domain-, origin-, address-, chain-, genesis-, nonce-, expiry-, and scope-bound proof for creating an off-chain session. In the source implementation, approval also persists the origin as a connected site, allowing account-address visibility while the wallet is unlocked until the user revokes that connection.
Economic transaction requests remain unavailable through this documented contract. Do not build against the former hypothetical lyth_requestAccounts, lyth_signChallenge, or lyth_requestTransaction examples.
1. Issue the challenge on the server
Section titled “1. Issue the challenge on the server”Create a short-lived request with exactly these fields. This application object is type-checked by the docs gate, but it is not yet a WalletAuthChallengeV1: the wallet adds the required address after approval.
import { encodeWalletAuthNonceV1 } from "@monolythium/core-sdk";
export function issueRequest(genesisHash: string) { if (!genesisHash.match(/^0x[0-9a-f]{64}$/)) { throw new Error("Pin the full genesis hash from the chain registry"); } const issuedAt = new Date();
return { version: "1", domain: "example.app", origin: "https://example.app", uri: "https://example.app/", chainId: "69420", genesisHash, nonce: encodeWalletAuthNonceV1(crypto.getRandomValues(new Uint8Array(32))), issuedAt: issuedAt.toISOString(), expirationTime: new Date(issuedAt.getTime() + 120_000).toISOString(), scopes: ["session:read"], };}Store the request server-side before returning it. The active address is deliberately absent: the wallet inserts its selected address after approval.
2. Ask the wallet once
Section titled “2. Ask the wallet once”The provider call below is browser integration pseudocode. It is not run by the SDK snippet gate. The provider method is available in the browser wallet’s v0.4.5 GitHub prerelease; store installation remains pending.
if (!window.monolythium) throw new Error("Monolythium Wallet not found");
const proof = await window.monolythium.request({ method: "monolythium_authenticate", params: request,});The wallet compares every server-issued field exactly, binds origin and network to the trusted browser context and active pinned network, prompts the user, and inserts its selected address as the sole wallet-added challenge field. It binds that address to the proof public key and returns a canonical WalletAuthProofV1.
After approval, the source implementation also persists the origin in Connected sites and exposes the selected address to that connected origin while the wallet is unlocked. That persistent visibility is a separate permission from the short-lived proof and must be disclosed in the consent UI.
Handle user rejection (4001), unsupported method (4200), a locked or unconfigured wallet, wrong network, expiry, and rate limiting. Never fall back to generic message signing when the method is missing.
3. Verify and consume on the server
Section titled “3. Verify and consume on the server”This verifier helper is part of the executable @monolythium/[email protected] snippet gate:
import { verifyWalletAuthProofV1 } from "@monolythium/core-sdk";
export function verifyProof(proof: unknown) { return verifyWalletAuthProofV1(proof, { now: new Date(), clockSkewSeconds: 5, });}Then compare every server-issued signed field exactly with the stored request. The stored request intentionally has no address: accept proof.challenge.address as the sole wallet-added field and require the SDK’s public-key/address binding check to pass. Enforce the expected origin, network, and scopes, then atomically consume the nonce. Only after all checks succeed should the application create a session.
verifyWalletAuthProofV1 verifies canonical structure, freshness, public-key/address binding, and the ML-DSA-65 signature. It cannot know whether your server issued the nonce or whether your application should grant a requested scope; those checks remain application policy.
Separate revocation domains
Section titled “Separate revocation domains”Proof expiry, application-session revocation, and wallet connection revocation are independent. A website must expire and revoke its own cookie or token. The user must remove the origin from the wallet’s Connected sites screen to stop future account visibility. Revoking either side does not automatically revoke the other, so user-facing sign-out guidance should describe both actions.
Availability
Section titled “Availability”The SDK implementation is released in @monolythium/[email protected]. Browser-wallet support under monolythium_authenticate is included in the v0.4.5 GitHub prerelease, but the current v0.4.4 store build predates wallet-auth v1. Feature-detect the method and distinguish prerelease installation from store availability.
Transaction boundary
Section titled “Transaction boundary”Authentication and connected-site visibility do not move value or authorize future signing. A future transaction API needs a separately versioned contract, complete review UI, and its own release evidence. Stele currently keeps economic writes and hosted signing disabled.