{"_id":"@az-spaces/aza-miniapp-sdk","name":"@az-spaces/aza-miniapp-sdk","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@az-spaces/aza-miniapp-sdk","version":"1.0.0","description":"SDK for building Aza Mini Apps. Provides TypeScript types and bridge helpers for window.aza.","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","publish:npm":"npm publish --access public --registry https://registry.npmjs.org/","publish:github":"npm publish --access public --registry https://npm.pkg.github.com/"},"publishConfig":{"registry":"https://npm.pkg.github.com/"},"repository":{"type":"git","url":"git+https://github.com/AZ-SPACES/project404.git"},"peerDependencies":{"react":">=17"},"peerDependenciesMeta":{"react":{"optional":true}},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.4.0","@types/react":"^18.0.0"},"keywords":["aza","miniapp","sdk","fintech","ghana"],"license":"MIT","_id":"@az-spaces/aza-miniapp-sdk@1.0.0","gitHead":"3f54c71877e45e876acd422904d016f4e0917aaf","bugs":{"url":"https://github.com/AZ-SPACES/project404/issues"},"homepage":"https://github.com/AZ-SPACES/project404#readme","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-atgCoyvYdF8aKhRGeN0HFwJfixv/tvX0/ZctRFesjjkasyvZB+s9eWwGlg5mpYCVk6eACDYMQoXD+3CzkD85uA==","shasum":"2c9cc91af1298d92ce1da006e1310fad5f3f815d","tarball":"https://registry.npmjs.org/@az-spaces/aza-miniapp-sdk/-/aza-miniapp-sdk-1.0.0.tgz","fileCount":8,"unpackedSize":41195,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICcXLzSzpqBPDVXHYTXWPYzT1pwE7LKFQ5LQZUaFK71SAiEAyL1+Uw7FQs/SiDsbUp1FknRFitYU9+QcnaT4RdEEdYc="}]},"_npmUser":{"name":"csdussey","email":"caleb.dussey04@gmail.com"},"directories":{},"maintainers":[{"name":"csdussey","email":"caleb.dussey04@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aza-miniapp-sdk_1.0.0_1781348335633_0.9728979518648717"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-13T10:58:55.495Z","1.0.0":"2026-06-13T10:58:55.792Z","modified":"2026-06-13T10:58:56.021Z"},"maintainers":[{"name":"csdussey","email":"caleb.dussey04@gmail.com"}],"description":"SDK for building Aza Mini Apps. Provides TypeScript types and bridge helpers for window.aza.","homepage":"https://github.com/AZ-SPACES/project404#readme","keywords":["aza","miniapp","sdk","fintech","ghana"],"repository":{"type":"git","url":"git+https://github.com/AZ-SPACES/project404.git"},"bugs":{"url":"https://github.com/AZ-SPACES/project404/issues"},"license":"MIT","readme":"# @jumpspaces/aza-miniapp-sdk\n\nTypeScript SDK for building **Aza Mini Apps**.\n\nThe Aza native app injects `window.aza` into your WebView automatically — you don't ship any runtime code. This package gives you full TypeScript types and helpers so your IDE autocompletes correctly and your code is type-safe.\n\n---\n\n## Installation\n\n**From npm (public):**\n```bash\nnpm install @jumpspaces/aza-miniapp-sdk\n```\n\n**From GitHub Packages (AZ-SPACES org members):**\n```bash\n# Add to your project's .npmrc:\n# @az-spaces:registry=https://npm.pkg.github.com/\n# //npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN\n\nnpm install @az-spaces/aza-miniapp-sdk\n```\n\n---\n\n## Quick start\n\n```ts\nimport { waitForAza } from '@jumpspaces/aza-miniapp-sdk';\n\nconst aza = await waitForAza();\nconst user = await aza.getUser();\nconsole.log(`Hello, ${user.firstName}!`);\n```\n\n---\n\n## API reference\n\n### `waitForAza(timeoutMs?): Promise<AzaSDK>`\n\nResolves with the bridge once it is ready. Safe to call at any point — if the bridge is already injected it resolves immediately; otherwise it waits for the `azaReady` event (dispatched before your page's first script runs).\n\n```ts\nconst aza = await waitForAza();   // default 5 s timeout\n```\n\n### `getAza(): AzaSDK`\n\nSynchronous version. Throws `AzaNotAvailableError` if the bridge isn't present yet. Use `waitForAza()` unless you are certain the bridge is already available (e.g. inside an event handler that runs after `azaReady`).\n\n### `isInsideAza(): boolean`\n\nReturns `true` when running inside the Aza app. Use this to gracefully degrade when your app is also served standalone (useful during local development).\n\n```ts\nif (isInsideAza()) {\n  const aza = getAza();\n  // ...\n} else {\n  // show a \"Open in Aza\" banner\n}\n```\n\n### `useAza(timeoutMs?): AzaHookState` *(React only)*\n\nReact hook version.\n\n```tsx\nimport { useAza } from '@jumpspaces/aza-miniapp-sdk';\n\nfunction App() {\n  const { status, aza } = useAza();\n\n  if (status === 'loading')     return <Spinner />;\n  if (status === 'unavailable') return <p>Please open this in Aza.</p>;\n\n  return <button onClick={() => aza.close()}>Close</button>;\n}\n```\n\n---\n\n## `AzaSDK` methods\n\nAll methods return a `Promise` that rejects with an `Error` if the operation fails or the required permission was not granted.\n\n### `aza.getUser() → Promise<AzaUser>`\n\nReturns the authenticated user's profile. Always available once the user has given consent.\n\n```ts\nconst user = await aza.getUser();\n// { username, firstName, lastName, avatarUrl, phone?, email? }\n```\n\n`phone` and `email` are only present if your app declared `USER_PHONE` / `USER_EMAIL` in its permissions and the user approved them.\n\n### `aza.getBalance() → Promise<AzaBalance>`\n\nReturns the user's current wallet balance in GHS.\n\nRequires: `READ_BALANCE` permission.\n\n```ts\nconst { balance } = await aza.getBalance();\n// { balance: 245.50 }\n```\n\n### `aza.requestPayment(params) → Promise<AzaPaymentResult>`\n\nShows a **native confirmation dialog** in Aza before any money moves. The Promise resolves only after the user taps \"Confirm\".\n\nRequires: `MAKE_PAYMENTS` permission.\n\n```ts\nconst result = await aza.requestPayment({\n  amount: 5.00,\n  recipientIdentifier: 'your_aza_username',  // your Aza account\n  note: 'Premium subscription',\n  idempotencyKey: crypto.randomUUID(),        // generate a fresh key per attempt\n});\n// { transactionId, status: 'COMPLETED', amount, recipientUsername, note }\n```\n\n**Important:** Generate a new `idempotencyKey` for every new payment intent. Reusing the same key on a retry is safe — Aza will return the original result without charging again.\n\n### `aza.close() → Promise<void>`\n\nCloses the mini app and returns the user to the Aza hub.\n\n### `aza.share(options) → Promise<void>`\n\nOpens the native Aza share sheet.\n\n```ts\nawait aza.share({ title: 'Check this out', message: 'I just paid with Aza!' });\n```\n\n---\n\n## Declaring permissions\n\nPermissions must be declared when you submit your app via the Aza Developer dashboard. Users see them on a consent sheet on first launch.\n\n| Permission key      | What it grants                                    |\n|---------------------|---------------------------------------------------|\n| `USER_PROFILE`      | name, username, avatar (always required)          |\n| `USER_PHONE`        | phone number                                      |\n| `USER_EMAIL`        | email address                                     |\n| `MAKE_PAYMENTS`     | initiate payments from the user's Aza wallet      |\n| `READ_BALANCE`      | read the user's wallet balance                    |\n| `READ_TRANSACTIONS` | read recent transaction history *(coming soon)*   |\n\n---\n\n## Development\n\nDuring local development `window.aza` is not available (no native bridge). Use `isInsideAza()` to detect this and show a fallback, or mock the bridge:\n\n```ts\n// dev-mock.ts  (never ship this to production)\nif (process.env.NODE_ENV === 'development' && !window.aza) {\n  window.aza = {\n    version: 'mock',\n    getUser:        async () => ({ username: 'testuser', firstName: 'Test', lastName: 'User', avatarUrl: null }),\n    getBalance:     async () => ({ balance: 100.00 }),\n    requestPayment: async (p) => ({ transactionId: 'mock-tx', status: 'COMPLETED', amount: p.amount, recipientUsername: p.recipientIdentifier, note: p.note ?? null }),\n    close:          async () => {},\n    share:          async () => {},\n  };\n}\n```\n\n---\n\n## App URL requirements\n\n- Must use **HTTPS**. HTTP URLs are rejected at submission time.\n- Must be reachable from a mobile WebView (no localhost).\n- Your server must not block WebView user agents.\n","readmeFilename":"README.md","_rev":"1-0746e00ec36e67d64e922d0d10102c1b"}