{"_id":"@brah.ma/aham","_rev":"8-e6e2f5996a17e20e00d592de26062dba","name":"@brah.ma/aham","dist-tags":{"latest":"1.0.7"},"versions":{"1.0.0":{"name":"@brah.ma/aham","version":"1.0.0","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.0","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"549a953210982878bdeade87e208507b4dd33f1e","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.0.tgz","fileCount":18,"integrity":"sha512-+sIOakfeQxte/sbqAizt6opuCY6IPGf+8KHhYccDqoSd/H6NqdAa+bWkIZOQYJy2sdm7s7xPpIjIQrTDmb+epg==","signatures":[{"sig":"MEQCIE6vsAAjOHlOpFkRlm4WFU1C+GHAmJMr/KFAImlR+nrmAiBrLRYdkwhRQxqlLJfHmv2hOJEvUnZYNQ6Tlmagk1MEGQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105671},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.0_1772805787256_0.23181622807383473","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@brah.ma/aham","version":"1.0.1","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.1","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"549474e4c8677cf2a740f95cd797ca8d72dc0120","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.1.tgz","fileCount":18,"integrity":"sha512-n3JCMwzUhQp3OnynGpwi3cMGAy0ZH7WJa0252646KIOiooUzKka1PM0Ru5nfg7tSDDnFMAg00vmr8UUO2f2JnQ==","signatures":[{"sig":"MEYCIQD9PiHp1LS3AG7hWb94Ijvol8bBodEiwpNzfTho2Bfs8wIhAIG80LxIRnrOuscqvBEgz4qdT1GoYefsEl8//SeiLnj2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105673},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.1_1772806471387_0.7890900353131651","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@brah.ma/aham","version":"1.0.2","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.2","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"db2d9a899a1d9661bc5ce8055640c3cd4ce78485","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.2.tgz","fileCount":18,"integrity":"sha512-zdm4F6hEXuhqzzyhGx8M5r61AjBNsZHP+vF0uJCzIImTV4G3QDWIgQdm0Jdq6tVybv3L2jLjrchkoJeJpLcV/Q==","signatures":[{"sig":"MEQCIG9+opzhMxO7eJbFVSEeHJhcng1Sp2Ut6r4SgzuL0XhJAiBsgoO//E3UnUFtF/qR/t+b9qKil5p4+EqCw8ybKYOnqg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105673},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.2_1772815457374_0.5881175697680399","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@brah.ma/aham","version":"1.0.3","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.3","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"03ec5605afdca02f36b786a86f8ebc2a6d3f1952","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.3.tgz","fileCount":18,"integrity":"sha512-ajxXi+50biFYhGjVSnejD6ydxQgnZVgr+t0q+3zgQ9ayR+cOaTZvrPFiu+Gq7K8u2vpLZWYahGVnnn+Oul+ffA==","signatures":[{"sig":"MEQCIGz8lf5TCE01o0rjuCt3sbYOQfhnN7ttOFnoKRaoNxsZAiAfFtJrto6xCBrmJ1v982l2Pw4EtXYyug5hUsm+qSjzpg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105673},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.3_1772816116836_0.6905961602938853","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@brah.ma/aham","version":"1.0.4","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.4","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"73f63c8e26080608ec1f54fc20cd9c25ef475412","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.4.tgz","fileCount":18,"integrity":"sha512-cvpY3PFbFqOAA0QtjjQp9rDHnxiR5GcMRRyqOdnjlyHoHWyqN19Fg+n+XD/hMwKabyubK2oDy6/+DdkE22NMNQ==","signatures":[{"sig":"MEQCIFKedKneoceUw5Ici2DTaWULFz7U3vuiDSFf3T+cT6/eAiAFmgJAkd4f6eaVGNa5XQnyJPF/LjHMmqAmGy5n2eLbQw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107429},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.4_1772817574519_0.5162902579620487","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@brah.ma/aham","version":"1.0.5","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.5","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"efe4803b6e4db19fee471a4ec7366ac26c1a4349","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.5.tgz","fileCount":18,"integrity":"sha512-hkLZo3GYqqmER2RgULHEf3W74QlPd/QjCNQUmcDAg834CkWuE7V0aM0zdRYW+GYQ/U7xg0s/88yAIVh4+8of8A==","signatures":[{"sig":"MEUCIHKtQVpq1ZyKW0dENHN+4nk7o0M3ELitYvQY3ERAaiQVAiEAtxjKui9R2f94xA3Vk3Yqg6MqsNiVsGJicozgpZqoJ9A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107960},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.5_1772818024456_0.7916700050714709","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@brah.ma/aham","version":"1.0.6","keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","_id":"@brah.ma/aham@1.0.6","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"dist":{"shasum":"500466b72babda1daaf4a8354ca7a38528a3419d","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.6.tgz","fileCount":18,"integrity":"sha512-vpMRkPt40iHf4hP8PcbFSnG3HeycTmWN9+e+ASTMK/vs75jWaZNMl3SYeMa58chuW8GvuoDZ2LTzPIIQcMePSA==","signatures":[{"sig":"MEUCIQCqAUmd0CFRfWFZp0N5fdCRUl8PsPS4TcluXJTiWQmFyQIgFKy4FrUmIBgzQaUpf4Uvxnf9Mlx2eGYC50oq9obLL9c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107960},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"_npmVersion":"11.8.0","description":"Brahma OS Identity Toolkit","directories":{},"_nodeVersion":"22.22.0","dependencies":{"clsx":"^2.1.1","lucide-react":"^0.575.0","framer-motion":"^12.34.3","@brah.ma/sthan":"file:../sthan","tailwind-merge":"^3.5.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.4","typescript":"^5.9.3","@types/react":"^19.2.14"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/aham_1.0.6_1772818045879_0.7408450315862036","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@brah.ma/aham","version":"1.0.7","description":"Brahma OS Identity Toolkit","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.mjs","require":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsup","dev":"tsup --watch"},"keywords":[],"author":{"name":"BrahmaOS"},"license":"ISC","peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"dependencies":{"@brah.ma/sthan":"file:../sthan","clsx":"^2.1.1","framer-motion":"^12.34.3","lucide-react":"^0.575.0","tailwind-merge":"^3.5.0"},"devDependencies":{"@types/react":"^19.2.14","react":"^19.2.4","tsup":"^8.5.1","typescript":"^5.9.3"},"gitHead":"e0fd13e9f7f372847c1a09494f400e4225f7962e","_id":"@brah.ma/aham@1.0.7","_nodeVersion":"22.22.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-oSzihQZiGWHyQBiKO8SMlJMKVjEfc+zYviAwtvnqC3bunYz2cNk/9nHPiy86NSNfcxOf2aRECQd34MjUHKVBPQ==","shasum":"98b9f642f973adea08a555950cb5dbd9279715c8","tarball":"https://registry.npmjs.org/@brah.ma/aham/-/aham-1.0.7.tgz","fileCount":18,"unpackedSize":110323,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDrxXpno2uU4EdVPKhamMnVviUo67TX7PXNQYTuJiFpywIhANdtMLRngWCGvcosSG8/g6LazISqEjZDrqREQE3UcPjw"}]},"_npmUser":{"name":"belikebrahma","email":"belikebrahma@gmail.com"},"directories":{},"maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aham_1.0.7_1775157355035_0.5572572333385817"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-06T14:03:07.147Z","modified":"2026-04-02T19:15:55.330Z","1.0.0":"2026-03-06T14:03:07.414Z","1.0.1":"2026-03-06T14:14:31.541Z","1.0.2":"2026-03-06T16:44:17.530Z","1.0.3":"2026-03-06T16:55:16.982Z","1.0.4":"2026-03-06T17:19:34.699Z","1.0.5":"2026-03-06T17:27:04.595Z","1.0.6":"2026-03-06T17:27:26.025Z","1.0.7":"2026-04-02T19:15:55.205Z"},"author":{"name":"BrahmaOS"},"license":"ISC","keywords":[],"description":"Brahma OS Identity Toolkit","maintainers":[{"name":"belikebrahma","email":"belikebrahma@gmail.com"}],"readme":"# @brah.ma/aham — SDK V3\n\n> Liquid SSO + Unified Karma + On-Chain Tokens for the Brahma ecosystem.\n\n---\n\n## Table of Contents\n\n1. [Installation](#installation)\n2. [Quick Start (3 Lines)](#quick-start)\n3. [Upgrading from V2](#upgrading-from-v2)\n4. [BrahmaProvider](#brahmaprovider)\n5. [Authentication (Liquid SSO)](#authentication)\n   - [useAham Hook](#useaham)\n   - [AhamInitiateButton](#ahaminitiatebutton)\n   - [Omni-Flow Modes](#omni-flow-modes)\n   - [Action Interception](#action-interception)\n6. [Session Management](#session-management)\n   - [useBrahmaSession](#usebrahmasession)\n   - [useBrahmaAPI](#usebrahmaapi)\n7. [Karma System](#karma-system)\n   - [useKarma](#usekarma)\n   - [Multi-Denomination Support](#multi-denomination-support)\n   - [Chain Sync Lifecycle](#chain-sync-lifecycle)\n8. [On-Chain Tokens](#on-chain-tokens)\n   - [useTokens](#usetokens)\n9. [Utilities](#utilities)\n10. [API Reference](#api-reference)\n11. [Security](#security)\n\n---\n\n## Installation\n\n```bash\nnpm install @brah.ma/aham @brah.ma/sthan\n```\n\n**Peer dependencies** (required in your project):\n```bash\nnpm install react react-dom framer-motion lucide-react clsx tailwind-merge\n```\n\n---\n\n## Quick Start\n\nThree lines to authenticate a user on any Brahma website:\n\n```tsx\nimport { BrahmaProvider, AhamInitiateButton } from '@brah.ma/aham';\n\nexport default function App() {\n  return (\n    <BrahmaProvider config={{ ahamGatewayUrl: \"https://aham.brah.ma/gateway\" }}>\n      <AhamInitiateButton onVerified={(user) => console.log(\"Welcome:\", user)} />\n    </BrahmaProvider>\n  );\n}\n```\n\nThat's it. The button handles the entire SSO flow, session persistence, and token management.\n\n---\n\n## Upgrading from V2\n\n### What Changed\n\n| Feature | V2 (aham-auth-sdk.js) | V3 (@brah.ma/aham) |\n|---|---|---|\n| **Architecture** | Vanilla JS class (`AhamAuth`) | React hooks + Context Provider |\n| **SSO** | Popup only | Popup, Redirect, Silent (Omni-Flow) |\n| **Karma** | Single `karmaPoints` integer | Multi-denomination (KARMA, PUNYA, DHANA, ...) |\n| **Web3** | Not integrated | Unified — one call for Web2 + Web3 sync |\n| **Sessions** | `localStorage` with manual restore | Auto-restore via `BrahmaProvider` |\n| **API Calls** | Manual `fetch` with `Bearer` token | `useBrahmaAPI` hook with auto-auth |\n\n### Migration Steps\n\n#### Step 1: Replace the script tag\n\n```diff\n- <script src=\"https://aham.brah.ma/aham-auth-sdk.js\"></script>\n- <script>\n-   window.ahamAuth = new AhamAuth({ authDomain: 'https://aham.brah.ma' });\n- </script>\n+ npm install @brah.ma/aham @brah.ma/sthan\n```\n\n#### Step 2: Wrap your app in `BrahmaProvider`\n\n```tsx\n// _app.tsx or layout.tsx\nimport { BrahmaProvider } from '@brah.ma/aham';\n\nexport default function App({ children }) {\n  return (\n    <BrahmaProvider config={{\n      ahamGatewayUrl: \"https://aham.brah.ma/gateway\",\n      ahamApiUrl: \"https://aham.brah.ma\",\n    }}>\n      {children}\n    </BrahmaProvider>\n  );\n}\n```\n\n#### Step 3: Replace V2 API calls\n\n```diff\n// Before (V2)\n- const isLoggedIn = window.ahamAuth.isAuthenticated();\n- const user = window.ahamAuth.getUser();\n- await window.ahamAuth.addKarma(5, 'page_visit');\n\n// After (V3)\n+ const { isAuthenticated, user } = useBrahmaSession();\n+ const { add } = useKarma();\n+ await add('KARMA', 5, 'page_visit');\n```\n\n#### Step 4: Replace the login button\n\n```diff\n- <button onclick=\"window.ahamAuth.login()\">Login</button>\n+ <AhamInitiateButton\n+   flow=\"popup\"\n+   onVerified={(payload) => console.log('User:', payload)}\n+ />\n```\n\n---\n\n## BrahmaProvider\n\nWraps your entire app. Manages shared auth state, session auto-restore, and config.\n\n```tsx\nimport { BrahmaProvider } from '@brah.ma/aham';\n\n<BrahmaProvider config={{\n  ahamGatewayUrl: \"https://aham.brah.ma/gateway\",\n  ahamApiUrl: \"https://aham.brah.ma\",\n  flow: \"popup\",                    // Default SSO flow\n  sessionMaxAge: 3600000,           // 1 hour (ms)\n}}>\n  <App />\n</BrahmaProvider>\n```\n\n### Config Options\n\n| Prop | Type | Default | Description |\n|---|---|---|---|\n| `ahamGatewayUrl` | `string` | `https://aham.brah.ma/gateway` | URL of the SSO gateway |\n| `ahamApiUrl` | `string` | `https://aham.brah.ma` | Base URL for API calls |\n| `flow` | `'popup' \\| 'redirect' \\| 'silent'` | `'popup'` | Default authentication flow |\n| `sessionMaxAge` | `number` | `3600000` | Session expiry in milliseconds |\n| `allowedOrigins` | `string[]` | `['https://aham.brah.ma']` | Origins accepted for `postMessage` |\n\n---\n\n## Authentication\n\n### useAham\n\nThe core SSO hook. Supports three authentication flows.\n\n```tsx\nimport { useAham } from '@brah.ma/aham';\n\nfunction LoginPage() {\n  const { initiate, intercept, isVerified, atmaSutra, error } = useAham({\n    flow: 'popup',\n    ahamGatewayUrl: 'https://aham.brah.ma/gateway',\n    onSuccess: (payload) => {\n      console.log('AtmaSutra:', payload.atmaSutra);\n      console.log('MoolSthan:', payload.moolSthan);\n    },\n    onFailed: (err) => console.error(err),\n  });\n\n  return <button onClick={initiate}>Login to Brahma</button>;\n}\n```\n\n#### Return Values\n\n| Property | Type | Description |\n|---|---|---|\n| `initiate()` | `() => Promise<void>` | Triggers the configured SSO flow |\n| `intercept(action, callback)` | `(string, () => void) => void` | Auth-gate an action |\n| `isInitiating` | `boolean` | True while SSO is in progress |\n| `isVerified` | `boolean` | True after successful auth |\n| `atmaSutra` | `string \\| null` | User's permanent ID |\n| `error` | `string \\| null` | Error message if auth failed |\n\n### AhamInitiateButton\n\nPre-built, animated \"hold-to-authenticate\" button.\n\n```tsx\nimport { AhamInitiateButton } from '@brah.ma/aham';\n\n<AhamInitiateButton\n  flow=\"popup\"\n  ahamGatewayUrl=\"https://aham.brah.ma/gateway\"\n  theme=\"mystical-dark\"          // \"mystical-dark\" | \"light\"\n  holdDurationMs={2000}          // How long to hold (ms)\n  onVerified={(payload) => {}}   // Success callback\n  onFailed={(err) => {}}         // Error callback\n/>\n```\n\n### Omni-Flow Modes\n\n#### `popup` — The Seamless Path\nOpens a popup window to `aham.brah.ma/gateway`. On success, sends the token back via a secure `postMessage`. No page navigation.\n\n```tsx\nuseAham({ flow: 'popup' })\n```\n\n**Best for:** SPAs, dashboards, any page where you don't want to lose state.\n\n#### `redirect` — The Traditional Path\nFull page redirect to the gateway. After auth, redirects back to your page with the token.\n\n```tsx\nuseAham({ flow: 'redirect' })\n```\n\n**Best for:** Server-rendered pages, mobile browsers that block popups.\n\n#### `silent` — The Invisible Path\nOpens a hidden `<iframe>` to check if the user already has an active Aham session. If yes, auto-authenticates without any UI. Falls back to `popup` if blocked by ITP (Safari/Brave).\n\n```tsx\nuseAham({ flow: 'silent' })\n```\n\n**Best for:** Auto-login on return visits, \"stay logged in\" experiences.\n\n### Action Interception\n\nGate any action behind authentication. If the user isn't logged in, the SDK triggers auth first, then automatically resumes the action after success.\n\n```tsx\nconst { intercept } = useAham({ flow: 'popup' });\n\nfunction handlePurchase() {\n  intercept('BUY_ITEM', () => {\n    // This only runs after the user is authenticated\n    processPurchase();\n  });\n}\n\n<button onClick={handlePurchase}>Buy Now — ₹99</button>\n```\n\n**Redirect flow handles this too:** The pending action is serialized to `localStorage` and replayed after the redirect returns.\n\n---\n\n## Session Management\n\n### useBrahmaSession\n\nQuick access to auth state. Reads from `BrahmaProvider` context.\n\n```tsx\nimport { useBrahmaSession } from '@brah.ma/aham';\n\nfunction Header() {\n  const { user, token, isAuthenticated, isLoading, logout, refresh } = useBrahmaSession();\n\n  if (isLoading) return <Spinner />;\n\n  return isAuthenticated ? (\n    <div>\n      <span>Welcome, {user.atmaSutra}</span>\n      <button onClick={logout}>Sign Out</button>\n    </div>\n  ) : (\n    <AhamInitiateButton />\n  );\n}\n```\n\n| Property | Type | Description |\n|---|---|---|\n| `user` | `BrahmaUser \\| null` | `{ atmaSutra, moolSthan, ...any }` |\n| `token` | `string \\| null` | JWT session token |\n| `isAuthenticated` | `boolean` | Quick auth check |\n| `isLoading` | `boolean` | True during initial session restore |\n| `logout()` | `() => void` | Clears all session data |\n| `refresh()` | `() => void` | Re-validates session from storage |\n\n### useBrahmaAPI\n\nAuthenticated fetch wrapper. Auto-attaches the `Bearer` token. Auto-handles `401` by calling `logout()`.\n\n```tsx\nimport { useBrahmaAPI } from '@brah.ma/aham';\n\nfunction ProfilePage() {\n  const { fetch: brahmaFetch } = useBrahmaAPI();\n\n  async function loadProfile() {\n    const res = await brahmaFetch('/api/user/profile');\n    const data = await res.json();\n    // Token is already attached, 401s auto-logout\n  }\n}\n```\n\n| Method | Signature | Description |\n|---|---|---|\n| `fetch` | `(endpoint: string, options?: RequestInit) => Promise<Response>` | Relative paths resolve against `ahamApiUrl` |\n\n---\n\n## Karma System\n\n### useKarma\n\n**One function for the user. Two layers behind the scenes.**\n\nEvery `add()` call instantly writes to Web2 (Prisma DB) AND queues an on-chain mint. The sync status is tracked per-record.\n\n```tsx\nimport { useKarma } from '@brah.ma/aham';\n\nfunction RewardPanel() {\n  const { balances, add, fetchBalances, getHistory, isLoading } = useKarma();\n\n  // Add karma — single call handles both Web2 and Web3\n  const reward = async () => {\n    await add('PUNYA', 5, 'temple_visit', 'Visited morning aarti');\n    await fetchBalances(); // Refresh UI\n  };\n\n  return (\n    <div>\n      <p>KARMA: {balances.KARMA?.web2 || 0}</p>\n      <p>PUNYA: {balances.PUNYA?.web2 || 0}</p>\n      <button onClick={reward}>+5 Punya</button>\n    </div>\n  );\n}\n```\n\n#### `add(denom, amount, action, description?)`\n\n| Param | Type | Description |\n|---|---|---|\n| `denom` | `string` | Token denomination: `'KARMA'`, `'PUNYA'`, `'DHANA'`, or any custom |\n| `amount` | `number` | Positive integer to add |\n| `action` | `string` | Machine-readable action ID (e.g. `'daily_sankalp'`) |\n| `description` | `string?` | Optional human-readable note |\n\n**Returns:** `{ transaction, balances }` — the transaction record and updated balances.\n\n#### Balance Shape\n\n```ts\nbalances = {\n  KARMA: { web2: 42, onChain: 35, pending: 7 },\n  PUNYA: { web2: 10, onChain: 10, pending: 0 },\n  DHANA: { web2: 0,  onChain: 0,  pending: 0 },\n}\n```\n\n| Field | Meaning |\n|---|---|\n| `web2` | Total accumulated in the database (instant) |\n| `onChain` | Confirmed on the Brahman blockchain |\n| `pending` | Queued for chain mint (web2 − onChain) |\n\n### Multi-Denomination Support\n\nDenominations are **open strings**, not enums. You can create any denomination without a schema migration:\n\n```ts\nadd('KARMA', 11, 'daily_sankalp');     // Standard karma\nadd('PUNYA', 5,  'temple_visit');      // Merit points\nadd('DHANA', 100, 'donation');         // Wealth tokens\nadd('SHAKTI', 1, 'meditation');        // Custom — works immediately!\n```\n\n### Chain Sync Lifecycle\n\n```\nadd('KARMA', 5, 'action')\n    │\n    ├── INSTANT → KarmaBalance.KARMA += 5 (DB)\n    ├── INSTANT → KarmaTransaction { chainStatus: 'pending' }\n    │\n    └── BACKGROUND (cron) → /api/karma/v3/sync\n        ├── Reads all pending transactions\n        ├── Batches per user per denom\n        ├── Mints ukarma on Brahman chain via Treasury\n        └── Updates chainStatus: 'minted', stores txHash\n```\n\nThe cron/sync is a backend concern. Partners never need to think about it — `add()` is fire-and-forget from their perspective.\n\n---\n\n## On-Chain Tokens\n\n### useTokens\n\nLive query of the Brahman blockchain for all token denominations.\n\n```tsx\nimport { useTokens } from '@brah.ma/aham';\n\nfunction WalletView() {\n  const { balances, refreshBalances, isLoading } = useTokens();\n\n  useEffect(() => { refreshBalances(); }, []);\n\n  return (\n    <div>\n      {Object.entries(balances).map(([denom, amount]) => (\n        <p key={denom}>{denom}: {amount}</p>\n      ))}\n     {/* Output: KARMA: 11, PUNYA: 10, DHANA: 0 */}\n    </div>\n  );\n}\n```\n\nNew denominations minted on the chain auto-appear — no SDK update needed.\n\n---\n\n## Utilities\n\n### Token Inspection (Client-Side)\n\n```ts\nimport { decodeToken, isTokenExpired, getTokenClaims } from '@brah.ma/aham';\n\nconst claims = decodeToken(jwt);\n// { atmaSutra, moolSthan, exp, iat, iss, aud }\n\nif (isTokenExpired(jwt)) {\n  // Trigger re-auth\n}\n\nconst valid = getTokenClaims(jwt); // null if expired\n```\n\n> **Note:** These decode the JWT payload without verifying the signature. Signature verification must happen server-side.\n\n### Session Persistence (Low-Level)\n\n```ts\nimport { saveSession, getSession, clearSession, isSessionValid } from '@brah.ma/aham';\n\nsaveSession(token, { atmaSutra: '...', moolSthan: '...' });\nconst session = getSession();   // { token, user, createdAt }\nconst valid = isSessionValid(); // true if < 1 hour old\nclearSession();                 // Wipes everything\n```\n\nYou normally don't need these — `BrahmaProvider` handles persistence automatically. These are for edge cases only.\n\n---\n\n## API Reference\n\n### Backend Routes (Aham Server)\n\n| Method | Route | Auth | Description |\n|---|---|---|---|\n| `POST` | `/api/karma/v3/add` | Bearer JWT | Add karma (any denom). Writes DB + queues chain. |\n| `GET` | `/api/karma/v3/balance` | Bearer JWT | Get all denom balances with sync status. `?history=true&limit=20` for tx log. |\n| `POST` | `/api/karma/v3/sync` | `x-cron-secret` | Admin: batch-mint pending karma on-chain. |\n| `GET` | `/api/tokens/balance` | Bearer JWT | Query live on-chain balances for all denoms. |\n| `POST` | `/api/tokens/distribute` | `x-cron-secret` | Admin: mint specific token amounts to a user. Body: `{ userId, amounts: { KARMA: 5 } }` |\n\n---\n\n## Security\n\n### PostMessage Origin Validation\nAll `popup` and `silent` flows use strict origin whitelisting. Only domains matching `*.brah.ma` and explicitly allowed origins can communicate via `postMessage`. Wildcard (`*`) is never used.\n\n### JWT Tokens\nSession tokens are short-lived JWTs (10 min). They contain `atmaSutra` and `moolSthan` claims. Raw private keys or mnemonics are **never** exposed to the client.\n\n### ITP Fallback\nSafari and Brave block third-party cookies/iframes. The `silent` flow auto-degrades to `popup` when ITP is detected, ensuring auth always works.\n\n### Session Storage\nSessions are stored in `localStorage` with timestamps. `BrahmaProvider` auto-validates session age on mount and clears expired data.\n\n---\n\n## Full Export Surface\n\n```ts\n// SSO\nuseAham, AhamInitiateButton\n\n// Context\nBrahmaProvider, useBrahmaContext\n\n// Session & Auth\nuseBrahmaSession, useBrahmaAPI\n\n// Karma & Tokens\nuseKarma, useTokens\n\n// Utilities\nsaveSession, getSession, clearSession, isSessionValid\ndecodeToken, isTokenExpired, getTokenClaims\n\n// Types\nBrahmaConfig, BrahmaContextValue, BrahmaUser, BrahmaSession\nBrahmaTokenClaims, AhamFlow, AhamConfig, AhamState\nKarmaBalances, KarmaDenomBalance, KarmaHistoryEntry, TokenBalances\n```\n","readmeFilename":"README.md"}