@echoxyz/sonar-react 0.0.1 → 0.1.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # @echoxyz/sonar-react
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 41247e9: Initial implementation of core/react wrapper.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [41247e9]
12
+ - @echoxyz/sonar-core@0.1.0
13
+
14
+ ## 0.0.3
15
+
16
+ ### Patch Changes
17
+
18
+ - 52ddd3f: Initial commit (empty)
19
+ - Updated dependencies [52ddd3f]
20
+ - @echoxyz/sonar-core@0.0.3
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # @echoxyz/sonar-react
2
+
3
+ React provider and hooks for Echo’s Sonar APIs, built on `@echoxyz/sonar-core`.
4
+
5
+ - Framework/router agnostic (works with React Router, Next.js, etc.).
6
+ - Handles PKCE OAuth redirect flow and token storage for the browser.
7
+ - Exposes a ready-to-use API client bound to a single `saleUUID`.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pnpm add @echoxyz/sonar-react @echoxyz/sonar-core
13
+ ```
14
+
15
+ Peer dependency: `react@>=18`.
16
+
17
+ ## Quick start
18
+
19
+ 1. Wrap your app with `SonarProvider`:
20
+
21
+ ```tsx
22
+ import { SonarProvider } from "@echoxyz/sonar-react";
23
+
24
+ export function AppRoot({ children }: { children: React.ReactNode }) {
25
+ return (
26
+ <SonarProvider
27
+ config={{
28
+ saleUUID: "<your-sale-uuid>",
29
+ clientUUID: "<your-oauth-client-id>",
30
+ redirectURI: window.location.origin + "/oauth/callback",
31
+ // Optional:
32
+ // apiURL: "https://api.echo.xyz",
33
+ // tokenStorageKey: "sonar:auth-token",
34
+ }}
35
+ >
36
+ {children}
37
+ </SonarProvider>
38
+ );
39
+ }
40
+ ```
41
+
42
+ 2. Trigger login with PKCE + redirect:
43
+
44
+ ```tsx
45
+ import { useSonarAuth } from "@echoxyz/sonar-react";
46
+
47
+ export function LoginButton() {
48
+ const { login, authenticated } = useSonarAuth();
49
+ if (authenticated()) {
50
+ return null;
51
+ }
52
+ return <button onClick={() => login()}>Sign in with Echo</button>;
53
+ }
54
+ ```
55
+
56
+ 3. Complete OAuth on your callback route/page:
57
+
58
+ ```tsx
59
+ import { useEffect } from "react";
60
+ import { useSonarAuth } from "@echoxyz/sonar-react";
61
+
62
+ export default function OAuthCallback() {
63
+ const { completeOAuth } = useSonarAuth();
64
+
65
+ useEffect(() => {
66
+ const params = new URLSearchParams(window.location.search);
67
+ const code = params.get("code");
68
+ const state = params.get("state");
69
+ if (!code || !state) {
70
+ return;
71
+ }
72
+ completeOAuth({ code, state }).catch((err) => {
73
+ console.error("OAuth completion failed", err);
74
+ });
75
+ }, [completeOAuth]);
76
+
77
+ return <p>Completing sign-in…</p>;
78
+ }
79
+ ```
80
+
81
+ 4. Call APIs using the low-level client:
82
+
83
+ ```tsx
84
+ import { useEffect } from "react";
85
+ import { useSonarAuth, useSonarClient } from "@echoxyz/sonar-react";
86
+ import { EntityType } from "@echoxyz/sonar-core";
87
+
88
+ export function Example() {
89
+ const { authenticated } = useSonarAuth();
90
+ const client = useSonarClient();
91
+
92
+ useEffect(() => {
93
+ if (!authenticated()) {
94
+ return;
95
+ }
96
+
97
+ (async () => {
98
+ const { Entities } = await client.listAvailableEntities({ saleUUID: "<your-sale-uuid>" });
99
+ if (Entities.length === 0) return;
100
+
101
+ const entity = Entities[0];
102
+ const pre = await client.prePurchaseCheck({
103
+ saleUUID: "<your-sale-uuid>",
104
+ entityUUID: entity.EntityUUID,
105
+ entityType: EntityType.USER,
106
+ walletAddress: "0x1234...abcd" as `0x${string}`,
107
+ });
108
+
109
+ if (pre.ReadyToPurchase) {
110
+ const permit = await client.generatePurchasePermit({
111
+ saleUUID: "<your-sale-uuid>",
112
+ entityUUID: entity.EntityUUID,
113
+ entityType: EntityType.USER,
114
+ walletAddress: "0x1234...abcd" as `0x${string}`,
115
+ });
116
+ console.log(permit.Signature, permit.Permit);
117
+ }
118
+
119
+ const alloc = await client.fetchAllocation({
120
+ saleUUID: "<your-sale-uuid>",
121
+ walletAddress: "0x1234...abcd" as `0x${string}`,
122
+ });
123
+ console.log(alloc);
124
+ })();
125
+ }, [authenticated, client]);
126
+
127
+ return null;
128
+ }
129
+ ```
130
+
131
+ ## API
132
+
133
+ - `SonarProvider`
134
+ - Props `config`:
135
+ - `saleUUID: string` (required) – Sale to scope API calls against.
136
+ - `clientUUID: string` (required) – Echo OAuth Client ID.
137
+ - `redirectURI: string` (required) – Your OAuth callback URI.
138
+ - `apiURL?: string` (default: `https://api.echo.xyz`) – API base URL.
139
+ - `tokenStorageKey?: string` (default: `sonar:auth-token`) – Browser storage key for the access token.
140
+
141
+ - `useSonarAuth()` → `{ authenticated, token?, login(), completeOAuth({ code, state }), logout() }`
142
+
143
+ - `useSonarClient()` → low-level `SonarClient` instance.
144
+
145
+ ## Notes
146
+
147
+ - Tokens are not auto-refreshed. On expiry, call `logout()` and re-run the OAuth flow.
148
+ - This package doesn’t depend on a specific router. Use it in Next.js, React Router, or any custom setup.
149
+ - Wallet addresses are typed as template literals `0x${string}`.
package/package.json CHANGED
@@ -1,26 +1,27 @@
1
1
  {
2
2
  "name": "@echoxyz/sonar-react",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
- "module": "./dist/index.mjs",
6
+ "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "import": "./dist/index.mjs",
11
- "require": "./dist/index.cjs",
12
- "types": "./dist/index.d.ts"
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
13
  }
14
14
  },
15
15
  "peerDependencies": {
16
16
  "react": ">=18"
17
17
  },
18
18
  "dependencies": {
19
- "@echoxyz/sonar-core": "0.0.1"
19
+ "@echoxyz/sonar-core": "0.1.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "tsup": "^8.0.0",
23
- "vitest": "^2.0.0"
23
+ "vitest": "^2.0.0",
24
+ "@types/react": "^18"
24
25
  },
25
26
  "repository": {
26
27
  "type": "git",
@@ -29,9 +30,15 @@
29
30
  "publishConfig": {
30
31
  "access": "public"
31
32
  },
33
+ "files": [
34
+ "dist",
35
+ "CHANGELOG.md",
36
+ "README.md",
37
+ "package.json"
38
+ ],
32
39
  "scripts": {
33
- "build": "tsup src/index.ts --format esm,cjs --dts",
34
- "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
40
+ "build": "tsup src/index.tsx --format esm,cjs --dts",
41
+ "dev": "tsup src/index.tsx --format esm,cjs --dts --watch",
35
42
  "test": "vitest run"
36
43
  }
37
44
  }
package/dist/index.cjs DELETED
File without changes
package/dist/index.d.cts DELETED
@@ -1,2 +0,0 @@
1
-
2
- export { }
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
-
2
- export { }
package/dist/index.js DELETED
File without changes
package/src/index.ts DELETED
File without changes