{"_id":"@1hub/onehub-sdk","_rev":"3-1b577f0eba1b7b488ff0158c64bd2b0c","name":"@1hub/onehub-sdk","dist-tags":{"latest":"1.2.0"},"versions":{"0.1.0":{"name":"@1hub/onehub-sdk","version":"0.1.0","keywords":["1hub","onehub","miniapp","flutter","webview","notifications","sso","qr","nfc"],"author":{"name":"1hub"},"license":"MIT","_id":"@1hub/onehub-sdk@0.1.0","maintainers":[{"name":"1hub","email":"dev@1hub.global"}],"homepage":"https://github.com/1hubholding/onehub-sdk#readme","bugs":{"url":"https://github.com/1hubholding/onehub-sdk/issues"},"dist":{"shasum":"926a5f4ba8eb95e0161c55683a23251dd642b557","tarball":"https://registry.npmjs.org/@1hub/onehub-sdk/-/onehub-sdk-0.1.0.tgz","fileCount":44,"integrity":"sha512-qWhnGPOpmrzDiqmRUHcGmurGf+QwSMnWkG/wRmUaihrCNyigSI/oz9ZMz1/SP52WQlgQ/eCjULHkl+j9wP7u1Q==","signatures":[{"sig":"MEUCIHXE/PuGGa7qIELqD6qqQfoZyhMi955w3a/FQpOfXprnAiEAgPyCun/BEtgkLeVec2XXajpEU9Dt2DhqOYG4VuDbJ5M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":46712},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"scripts":{"dev":"tsc --watch","lint":"eslint \"{src}/**/*.ts\"","build":"tsc","clean":"rm -rf dist","prepublishOnly":"rm -rf dist && tsc"},"_npmUser":{"name":"1hub","email":"dev@1hub.global"},"repository":{"url":"git+https://github.com/1hubholding/onehub-sdk.git","type":"git"},"_npmVersion":"11.9.0","description":"Frontend SDK for 1hub mini-apps — Flutter bridge handlers (QR, NFC, SSO, utility) and an HTTP client for the 1hub notification API.","directories":{},"_nodeVersion":"24.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"5.8.2","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/onehub-sdk_0.1.0_1779076550535_0.22917689298722266","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@1hub/onehub-sdk","version":"1.1.0","keywords":["1hub","onehub","miniapp","flutter","webview","notifications","sso","qr","nfc"],"author":{"name":"1hub"},"license":"MIT","_id":"@1hub/onehub-sdk@1.1.0","maintainers":[{"name":"1hub","email":"dev@1hub.global"}],"homepage":"https://github.com/1hubholding/onehub-sdk#readme","bugs":{"url":"https://github.com/1hubholding/onehub-sdk/issues"},"dist":{"shasum":"b92bf0c124eb48d23b2f9f1c371b85a36c27edd7","tarball":"https://registry.npmjs.org/@1hub/onehub-sdk/-/onehub-sdk-1.1.0.tgz","fileCount":47,"integrity":"sha512-Ueb225/5EXYI75mThoEhiE1w1K2xqK72mtEQufdwae8chT7xP/nUhIoe76bjFIi5ucAOjIUICJ+vbH6IgEFNmQ==","signatures":[{"sig":"MEQCIAhc8G9a4Hct3yl+KB/xxgN1GfVn0W2nrONQtEZYQwK+AiB+/X+LMeGn7wuVmYA4fQbtu+5CYvE1iCzW9f4KOnMoTw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48026},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"59b94a11fc58eecc7313f3dc20d8193364372a36","scripts":{"dev":"tsc --watch","lint":"eslint \"{src}/**/*.ts\"","build":"tsc","clean":"rm -rf dist","prebuild":"node scripts/generate-config.mjs","prepublishOnly":"rm -rf dist && node scripts/generate-config.mjs && tsc","generate-config":"node scripts/generate-config.mjs"},"_npmUser":{"name":"1hub","email":"dev@1hub.global"},"repository":{"url":"git+https://github.com/1hubholding/onehub-sdk.git","type":"git"},"_npmVersion":"11.9.0","description":"Frontend SDK for 1hub mini-apps — Flutter bridge handlers (QR, NFC, SSO, utility) and an HTTP client for the 1hub notification API.","directories":{},"_nodeVersion":"24.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"5.8.2","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/onehub-sdk_1.1.0_1779084962202_0.3873024393881559","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@1hub/onehub-sdk","version":"1.2.0","description":"Frontend SDK for 1hub mini-apps — Flutter bridge handlers (QR, NFC, SSO, utility), an HTTP client for the 1hub notification API, and QR login via RFC 8628 Device Authorization Grant.","license":"MIT","author":{"name":"1hub"},"repository":{"type":"git","url":"git+https://github.com/1hubholding/onehub-sdk.git"},"homepage":"https://github.com/1hubholding/onehub-sdk#readme","bugs":{"url":"https://github.com/1hubholding/onehub-sdk/issues"},"keywords":["1hub","onehub","miniapp","flutter","webview","notifications","sso","qr","nfc","oauth","login","qr-login","device-flow"],"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./react":{"import":"./dist/react/index.js","types":"./dist/react/index.d.ts"}},"publishConfig":{"access":"public"},"scripts":{"test":"vitest run","test:watch":"vitest","dev":"tsc --watch","build":"tsc","clean":"rm -rf dist","lint":"eslint \"{src}/**/*.ts\"","generate-config":"node scripts/generate-config.mjs","prebuild":"node scripts/generate-config.mjs","prepublishOnly":"rm -rf dist && node scripts/generate-config.mjs && tsc"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"devDependencies":{"@types/react":"^19.0.0","typescript":"5.8.2","vitest":"3.1.4"},"gitHead":"153675de545dc25f505e27370b97c3a5dda43533","_id":"@1hub/onehub-sdk@1.2.0","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-2Ej5FFk4iFtsuJv09NJsLiFUa4GDwvHLCoK0wTd0QFOwYs7X2+kxrawFHgcasQ1VJNkc7SCTXkW05D4wgfuJzg==","shasum":"c6ab09a723d429ea24ff839bd4a1741644735f14","tarball":"https://registry.npmjs.org/@1hub/onehub-sdk/-/onehub-sdk-1.2.0.tgz","fileCount":66,"unpackedSize":81697,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDIV5sbXHQYK3F+tmcxV39Ma6WhBydWrOsR6jTpG4AfRQIgWnp3yL1gEh3OYc1fK8UGPTm49aq5MjZoRQXxkj1wjlA="}]},"_npmUser":{"name":"1hub","email":"dev@1hub.global"},"directories":{},"maintainers":[{"name":"1hub","email":"dev@1hub.global"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/onehub-sdk_1.2.0_1779352913492_0.8218143974804499"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-18T03:55:50.400Z","modified":"2026-05-21T08:41:53.772Z","0.1.0":"2026-05-18T03:55:50.715Z","1.1.0":"2026-05-18T06:16:02.336Z","1.2.0":"2026-05-21T08:41:53.643Z"},"bugs":{"url":"https://github.com/1hubholding/onehub-sdk/issues"},"author":{"name":"1hub"},"license":"MIT","homepage":"https://github.com/1hubholding/onehub-sdk#readme","keywords":["1hub","onehub","miniapp","flutter","webview","notifications","sso","qr","nfc","oauth","login","qr-login","device-flow"],"repository":{"type":"git","url":"git+https://github.com/1hubholding/onehub-sdk.git"},"description":"Frontend SDK for 1hub mini-apps — Flutter bridge handlers (QR, NFC, SSO, utility), an HTTP client for the 1hub notification API, and QR login via RFC 8628 Device Authorization Grant.","maintainers":[{"name":"1hub","email":"dev@1hub.global"}],"readme":"# @1hub/onehub-sdk\n\nFrontend SDK for 1hub mini-apps. Three parts:\n\n- **Flutter bridge handlers** — `window.flutter_inappwebview.callHandler` wrappers for QR scan, NFC scan, SSO, and native utilities (toast, share, exit, contact support).\n- **Notification HTTP client** — server-to-server client for the 1hub notification API, authenticated with a provider API key.\n- **QR login** — RFC 8628 Device Authorization Grant for partner web apps to authenticate users via the 1hub mobile app.\n\n## Install\n\n```bash\nnpm install @1hub/onehub-sdk\n# react hooks (optional, only if you use the /react entry)\nnpm install react\n```\n\n## Notification client\n\nUsed by a mini-app's backend (or any JS runtime) to push notifications to 1hub accounts. Authenticates with an `x-api-key: pk_<keyId>.<secret>` header. The backend derives `provider` from the authenticated key, so you do not — and must not — send it in the body.\n\n```ts\nimport { createNotificationClient } from '@1hub/onehub-sdk';\n\nconst notifications = createNotificationClient({\n  apiKey: process.env.ONEHUB_API_KEY!, // 'pk_<keyId>.<secret>'\n});\n```\n\n> `baseUrl` defaults to `https://api.1hub.global`. Override it only if you point at a non-production environment.\n\n```ts\n// Single account\nawait notifications.sendToAccount({\n  accountId: '4e3a97f0-905a-4e26-931f-84193f138480',\n  title: 'Hello',\n  body: 'New activity in your mini-app',\n  tag: 'activity',\n  data: { deepLink: 'onehub://miniapp/ftu/home' },\n});\n\n// Multiple accounts\nawait notifications.sendToMultipleAccounts({\n  accountIds: ['acc-1', 'acc-2'],\n  title: 'System Announcement',\n  body: 'Scheduled maintenance tonight.',\n});\n```\n\n### Errors\n\nNon-2xx responses throw `NotificationRequestError`:\n\n```ts\nimport { NotificationRequestError } from '@1hub/onehub-sdk';\n\ntry {\n  await notifications.sendToAccount({ /* ... */ });\n} catch (err) {\n  if (err instanceof NotificationRequestError) {\n    console.error(err.status, err.code, err.message);\n  }\n}\n```\n\n| `status` | `code`              | Cause                                                  |\n|---------:|---------------------|--------------------------------------------------------|\n| 401      | `MISSING_API_KEY`   | `x-api-key` header missing                             |\n| 401      | `INVALID_API_KEY`   | Key malformed, unknown, inactive, or secret mismatch   |\n| 403      | `INSUFFICIENT_SCOPE`| Key valid but lacks `notifications:send` scope         |\n| 400      | (validation)        | Missing/invalid fields in the request body             |\n\n## Flutter bridge handlers\n\nThese require the mini-app to be running inside the 1hub Flutter webview (`window.flutter_inappwebview` must be present).\n\n```ts\nimport {\n  openQrScan, closeQrScan, onQrEvent,\n  openNfcScan, closeNfcScan, onNfcEvent,\n  requestSSOCode,\n  showToast, shareFile, contactSupport, exitMiniApp,\n} from '@1hub/onehub-sdk';\n\nconst sso = await requestSSOCode({\n  clientId: 'your-client-id',\n  redirectUri: 'https://your-app.example/callback',\n  scope: 'openid profile',\n});\n\nawait showToast({ message: 'Đã lưu!' });\n```\n\n### React hooks\n\n```ts\nimport { useSSO, useQrScan, useNfcScan } from '@1hub/onehub-sdk/react';\n```\n\n## Login with 1hub via QR code\n\n`startQrLogin` implements the RFC 8628 Device Authorization Grant. A partner web app displays a QR code; the user scans it with the 1hub mobile app and approves; the partner receives OAuth tokens.\n\n**Security note:** `clientSecret` must never be embedded in a browser SPA. Proxy the `startQrLogin` call through your backend server to keep the secret confidential.\n\nTo get a `clientId` and `clientSecret`, contact 1hub to register your OAuth client.\n\n```ts\nimport { startQrLogin, QrLoginError } from '@1hub/onehub-sdk';\nimport QRCode from 'qrcode'; // any QR library\n\nconst session = await startQrLogin({\n  clientId: 'your-client-id',\n  clientSecret: process.env.ONEHUB_CLIENT_SECRET!, // keep server-side!\n  scopes: ['openid', 'profile'],\n});\n\n// Render the QR code for the user to scan with the 1hub mobile app\nawait QRCode.toCanvas(document.getElementById('qr-canvas'), session.qrData);\n\n// Optionally display the user code as a fallback\nconsole.log('Or enter code:', session.userCode); // e.g. \"XB4M-9PQ2\"\n\n// Await the result\ntry {\n  const tokens = await session.result;\n  console.log('Access token:', tokens.access_token);\n  console.log('ID token:', tokens.id_token);\n} catch (err) {\n  if (err instanceof QrLoginError) {\n    switch (err.code) {\n      case 'expired':\n        console.error('QR code expired — ask the user to refresh');\n        break;\n      case 'denied':\n        console.error('User denied the login request');\n        break;\n      case 'cancelled':\n        console.log('Login cancelled by the app');\n        break;\n      default:\n        console.error('QR login failed:', err.code, err.message);\n    }\n  }\n}\n\n// Cancel polling if the user navigates away\nwindow.addEventListener('beforeunload', () => session.cancel());\n```\n\n### QrLoginSession\n\n| Property                  | Type                    | Description                                                  |\n|---------------------------|-------------------------|--------------------------------------------------------------|\n| `qrData`                  | `string`                | `verification_uri_complete` — encode as QR code              |\n| `userCode`                | `string`                | Human-readable code (e.g. `XB4M-9PQ2`) for manual entry     |\n| `verificationUri`         | `string`                | Base verification URL (without user_code query param)        |\n| `verificationUriComplete` | `string`                | Full verification URL including user_code query param        |\n| `sessionId`               | `string`                | Opaque session identifier (device_code) for diagnostics      |\n| `expiresIn`               | `number`                | Seconds until the session expires (typically 300)            |\n| `result`                  | `Promise<QrLoginResult>`| Resolves with tokens on approval, rejects with `QrLoginError`|\n| `cancel`                  | `() => void`            | Stops polling; `result` rejects with `code: 'cancelled'`     |\n\n### QrLoginErrorCode\n\n| Code             | Cause                                                    |\n|------------------|----------------------------------------------------------|\n| `expired`        | QR code TTL elapsed (300 s) — refresh the QR            |\n| `denied`         | User denied consent on the mobile app                    |\n| `cancelled`      | `session.cancel()` was called                            |\n| `network`        | Network failure after 3 consecutive retries              |\n| `invalid_client` | Bad `clientId` or `clientSecret`                         |\n| `invalid_grant`  | `device_code` not found or already consumed              |\n| `unknown`        | Unexpected error                                         |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}