pushwave-client 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # pushwave-client (alpha)
2
+
3
+ Expo/React Native SDK for the upcoming PushWave SaaS (work in progress). Goal: fetch the Expo push token and prepare app attestation (Android Play Integrity / iOS DeviceCheck) to secure notification delivery. The SaaS/backend validation is coming soon—consider this an early-stage project.
4
+
5
+ ---
6
+
7
+ ## Quick install
8
+
9
+ 1) Install the [SDK](https://www.npmjs.com/package/pushwave-client) and [Expo notifications](https://docs.expo.dev/versions/latest/sdk/notifications/) (peer requirement):
10
+ ```bash
11
+ npm install pushwave-client
12
+ npx expo install expo-notifications
13
+ ```
14
+
15
+ 2) Add the config plugin to your app.json / app.config.*:
16
+ ```json
17
+ {
18
+ "expo": {
19
+ "plugins": ["pushwave-client"]
20
+ }
21
+ }
22
+ ```
23
+
24
+ 3) Build native (EAS or dev client). Expo Go is not supported once native code is involved:
25
+ ```bash
26
+ eas build -p android --profile development
27
+ eas build -p ios --profile development
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Minimal usage
33
+
34
+ ```tsx
35
+ import { useEffect } from "react";
36
+ import { Alert } from "react-native";
37
+ import PushWaveClient from "pushwave-client";
38
+
39
+ export default function App() {
40
+ useEffect(() => {
41
+ (async () => {
42
+ const res = await PushWaveClient.init({ apiKey: "pw_dev_xxx" });
43
+ if (!res.success) {
44
+ Alert.alert("PushWave", res.message ?? "Init failed");
45
+ }
46
+ })();
47
+ }, []);
48
+
49
+ return /* …your UI… */;
50
+ }
51
+ ```
52
+
53
+ - `PushWaveClient.init` is async and returns `{ success: boolean; message?: string }`.
54
+ - Call it **once** at app startup (e.g., in `App.tsx` or a root component `useEffect`). Recalling it later is unnecessary.
55
+ - In `__DEV__`, the SDK may log additional info/errors (e.g., failed API calls) to help debugging.
56
+
57
+ ---
58
+
59
+ ## Notifications (expo-notifications)
60
+
61
+ - The SDK retrieves the user’s Expo push token. If the user denies notification permission, no push will be delivered and the token may not be available depending on platform/permission.
62
+ - On iOS, user permission is required to obtain a push token.
63
+ - On Android, Expo handles permission/channel setup; if the user refuses, no push is delivered.
64
+
65
+ ---
66
+
67
+ ## Attestation (current status)
68
+
69
+ - Backend validation is not live yet; it will arrive with the PushWave SaaS.
70
+ - Android (Play Integrity): will require a build distributed via the Play Store (internal/closed track) with Play App Signing + Play Integrity API enabled. No support for Expo Go / sideload.
71
+ - iOS (DeviceCheck): will require a real build (dev client or TestFlight), not Expo Go.
72
+ - For now, consider attestation non-blocking (the SDK may return a `disabled` flag until the SaaS is active).
73
+
74
+ ---
75
+
76
+ ## Compatibility
77
+
78
+ - Tested on the latest Expo SDK (54). No guarantees on earlier versions.
79
+ - Requires a native build (EAS or dev client).
80
+
81
+ ---
82
+
83
+ ## Links
84
+
85
+ - NPM: https://www.npmjs.com/package/pushwave-client
86
+ - GitHub: https://github.com/luruk-hai/pushwave-client#readme
87
+
88
+ ---
89
+
90
+ ## Roadmap (with SaaS)
91
+
92
+ - Server-side validation of Play Integrity / DeviceCheck tokens.
93
+ - Full attestation docs and Play Store setup (enable Integrity API, internal track).
94
+ - Complete registration flow with the PushWave backend.
@@ -5,10 +5,11 @@ export interface RegisterPushWaveResponse {
5
5
  success: boolean;
6
6
  message?: string;
7
7
  }
8
- export interface RegisterPushWaveOptions {
8
+ export interface RegisterPushWaveDTO {
9
9
  apiKey: string;
10
10
  expoToken: string;
11
11
  platform: string;
12
12
  appAttestation?: any;
13
+ environment: "development" | "production";
13
14
  }
14
15
  export default function registerPushWave({ apiKey }: RegisterPushWaveClient): Promise<RegisterPushWaveResponse>;
@@ -32,7 +32,8 @@ async function registerPushWave({ apiKey }) {
32
32
  apiKey: apiKey,
33
33
  expoToken: expoToken,
34
34
  platform: react_native_1.Platform.OS,
35
- appAttestation: appAttestation
35
+ appAttestation: appAttestation,
36
+ environment: __DEV__ ? "development" : "production"
36
37
  };
37
38
  try {
38
39
  const res = await (0, fetch_1.fetchApi)(path, options);
@@ -4,6 +4,7 @@ exports.fetchApi = fetchApi;
4
4
  const BASE_URL = "https://pushwave.luruk-hai.fr";
5
5
  async function fetchApi(path, data) {
6
6
  const url = BASE_URL + path;
7
+ console.log(data);
7
8
  const res = await fetch(url, {
8
9
  method: "POST",
9
10
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pushwave-client",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "PushWave Client, Expo Push Notifications SaaS SDK",
5
5
  "homepage": "https://github.com/luruk-hai/pushwave-client#readme",
6
6
  "bugs": {
@@ -0,0 +1,30 @@
1
+ export interface AndroidAttestationPayload {
2
+ status: "ok";
3
+ platform: "android";
4
+ nonce: string;
5
+ timestamp: number;
6
+ integrityToken: string;
7
+ }
8
+
9
+ export interface IosAttestationPayload {
10
+ status: "ok";
11
+ platform: "ios";
12
+ nonce: string;
13
+ timestamp: number;
14
+ deviceCheckToken: string;
15
+ }
16
+
17
+ export interface DisabledAttestation {
18
+ status: "disabled";
19
+ reason: string;
20
+ }
21
+
22
+ export interface SkippedAttestation {
23
+ status: "skipped";
24
+ }
25
+
26
+ export type ApplicationAttestation =
27
+ | AndroidAttestationPayload
28
+ | IosAttestationPayload
29
+ | DisabledAttestation
30
+ | SkippedAttestation;
@@ -1,39 +1,9 @@
1
1
  import { Buffer } from "buffer";
2
2
  import { Platform } from "react-native";
3
3
  import { getAndroidIntegrityToken, getDeviceCheckToken } from "./native";
4
+ import { ApplicationAttestation, AndroidAttestationPayload, DisabledAttestation, IosAttestationPayload } from "./index";
4
5
 
5
- export interface AndroidAttestationPayload {
6
- status: "ok";
7
- platform: "android";
8
- nonce: string;
9
- timestamp: number;
10
- integrityToken: string;
11
- }
12
-
13
- export interface IosAttestationPayload {
14
- status: "ok";
15
- platform: "ios";
16
- nonce: string;
17
- timestamp: number;
18
- deviceCheckToken: string;
19
- }
20
-
21
- export interface DisabledAttestation {
22
- status: "disabled";
23
- reason: string;
24
- }
25
-
26
- export interface SkippedAttestation {
27
- status: "skipped";
28
- }
29
-
30
- export type ApplicationAttestation =
31
- | AndroidAttestationPayload
32
- | IosAttestationPayload
33
- | DisabledAttestation
34
- | SkippedAttestation;
35
-
36
- export default async function getApplicationAttestation(apiKey: string): Promise<ApplicationAttestation> {
6
+ export async function getApplicationAttestation(apiKey: string): Promise<ApplicationAttestation> {
37
7
  if (!requiresAttestation(apiKey)) return { status: "skipped" };
38
8
 
39
9
  const { nonce, timestamp } = createNonce();
@@ -0,0 +1,2 @@
1
+ export * from "./attestation.types";
2
+ export * from "./getApplicationAttestation";
package/src/index.ts CHANGED
@@ -1,7 +1,4 @@
1
- import registerPushWave, {
2
- RegisterPushWaveClient,
3
- RegisterPushWaveResponse,
4
- } from "./registerPushWave";
1
+ import { registerPushWave, RegisterPushWaveClient, RegisterPushWaveResponse } from "./register";
5
2
 
6
3
  export interface PushWaveClientType {
7
4
  init(options: RegisterPushWaveClient): Promise<RegisterPushWaveResponse>;
@@ -0,0 +1,2 @@
1
+ export * from "./registerPushWave";
2
+ export * from "./registerPushWave.dto";
@@ -0,0 +1,16 @@
1
+ export interface RegisterPushWaveClient {
2
+ apiKey: string;
3
+ }
4
+
5
+ export interface RegisterPushWaveResponse {
6
+ success: boolean;
7
+ message?: string;
8
+ }
9
+
10
+ export interface RegisterPushWaveDTO {
11
+ apiKey: string;
12
+ expoToken: string;
13
+ platform: string;
14
+ appAttestation?: any;
15
+ environment: "development" | "production"
16
+ }
@@ -1,28 +1,12 @@
1
- import { fetchApi } from "./utils/fetch";
2
- import { getExpoToken } from "./utils/expoToken";
3
- import getApplicationAttestation from "./attestation/getApplicationAttestation";
1
+ import { fetchApi } from "../utils/fetch";
2
+ import { getExpoToken } from "../utils/expoToken";
4
3
  import { Platform } from "react-native";
5
- import { PWLogger } from "./utils/pwLogger";
6
- import { isSecretKey } from "./utils/apiKeyCheck";
4
+ import { PWLogger } from "../utils/pwLogger";
5
+ import { isSecretKey } from "../utils/apiKeyCheck";
6
+ import { RegisterPushWaveClient, RegisterPushWaveDTO, RegisterPushWaveResponse } from "./registerPushWave.dto";
7
+ import { getApplicationAttestation } from "../attestation/index";
7
8
 
8
- export interface RegisterPushWaveClient {
9
- apiKey: string;
10
- }
11
-
12
- export interface RegisterPushWaveResponse {
13
- success: boolean;
14
- message?: string;
15
- }
16
-
17
- export interface RegisterPushWaveOptions {
18
- apiKey: string;
19
- expoToken: string;
20
- platform: string;
21
- appAttestation?: any;
22
- environment: "development" | "production"
23
- }
24
-
25
- export default async function registerPushWave(
9
+ export async function registerPushWave(
26
10
  { apiKey }: RegisterPushWaveClient
27
11
  ): Promise<RegisterPushWaveResponse> {
28
12
 
@@ -52,7 +36,7 @@ export default async function registerPushWave(
52
36
 
53
37
  const path = "/v1/expo-tokens"
54
38
 
55
- const options: RegisterPushWaveOptions = {
39
+ const options: RegisterPushWaveDTO = {
56
40
  apiKey: apiKey,
57
41
  expoToken: expoToken,
58
42
  platform: Platform.OS,
@@ -7,6 +7,8 @@ export async function fetchApi<TResponse>(
7
7
 
8
8
  const url = BASE_URL + path;
9
9
 
10
+ console.log(data);
11
+
10
12
  const res = await fetch(url, {
11
13
  method: "POST",
12
14
  headers: {
File without changes