@echoxyz/sonar-react 0.0.3 → 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 +12 -1
- package/README.md +149 -0
- package/package.json +10 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
# @echoxyz/sonar-react
|
|
2
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
|
+
|
|
3
14
|
## 0.0.3
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
6
17
|
|
|
7
18
|
- 52ddd3f: Initial commit (empty)
|
|
8
19
|
- Updated dependencies [52ddd3f]
|
|
9
|
-
|
|
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
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
|
-
"module": "./dist/index.
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
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
|
|
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",
|
|
@@ -36,8 +37,8 @@
|
|
|
36
37
|
"package.json"
|
|
37
38
|
],
|
|
38
39
|
"scripts": {
|
|
39
|
-
"build": "tsup src/index.
|
|
40
|
-
"dev": "tsup src/index.
|
|
40
|
+
"build": "tsup src/index.tsx --format esm,cjs --dts",
|
|
41
|
+
"dev": "tsup src/index.tsx --format esm,cjs --dts --watch",
|
|
41
42
|
"test": "vitest run"
|
|
42
43
|
}
|
|
43
44
|
}
|