-
Notifications
You must be signed in to change notification settings - Fork 1
Flesh out README #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,134 @@ | ||
| # sonar-example-react | ||
|
|
||
| A React example app demonstrating integration with the Sonar API using `@echoxyz/sonar-react` and `@echoxyz/sonar-core` libraries. | ||
| A **frontend-focused** React example app demonstrating integration with the Sonar API using `@echoxyz/sonar-react` and `@echoxyz/sonar-core` libraries. | ||
|
|
||
| There is an integration guide for these libraries [here](https://docs.echo.xyz/sonar/integration-guides/react). | ||
|
|
||
| The example app demonstrates how to: | ||
| This example implements a client-side OAuth flow where tokens are managed entirely in the browser by the `@echoxyz/sonar-react` library. For a more secure backend approach where tokens are stored server-side, see [sonar-example-nextjs](https://github.com/sunrisedotdev/sonar-example-nextjs). | ||
|
|
||
| - Setup providers in `src/Provider.tsx` | ||
| - Authenticate with Sonar via the oauth flow | ||
| - See `src/components/auth/AuthenticationSection.tsx` on how to create the login/logout buttons | ||
| - See `src/pages/OAuthCallback.tsx` for an example of the oauth callback handler | ||
| - Prior to a sale going live, a way to list the state of all of a user's entities | ||
| - See `src/pages/Home.tsx` while in the `!saleIsLive` state | ||
| - When sale is live, display setup/eligibily state of the entity on Sonar that is linked to the currently connected wallet | ||
| - See `src/pages/Home.tsx` while in the `saleIsLive` state | ||
| - Surface the user's entity setup/eligibility state | ||
| - See components in `src/components/entity` | ||
| - Run prepurchase checks | ||
| - See `src/components/sale/PurchaseCard.tsx` for an example of how to run these checks and interpret the result | ||
| - Submit a purchase transaction to an example sale contract | ||
| - See the `ReadyToPurchaseSection` in `src/components/sale/PurchaseCard.tsx` for an example of how to generate a purchase permit and pass this to the contract, | ||
| using the `useSaleContract` hook in `src/hooks.ts` | ||
| ## Why Use the Frontend Approach? | ||
|
|
||
| ## Configuration | ||
| This approach is simpler to implement and can can be used by single-page applications (SPAs) that don't already have a backend. All authentication and API calls are handled client-side using React hooks. | ||
|
|
||
| By default this app is configured to point to use a test sonar sale and contract and should work out of the box. | ||
| If you want to point it at a different sale or contract, you can modify the env vars in `.env.local`. | ||
| However, since tokens are stored in the browser, this approach is less secure than a backend flow (as implemented in [sonar-example-nextjs](https://github.com/sunrisedotdev/sonar-example-nextjs)). | ||
|
|
||
| ## Running the app locally | ||
| ## Running the App Locally | ||
|
|
||
| By default this app is configured to use a test Sonar sale and contract and should work out of the box. If you want to point it at a different sale or contract, you can modify the env vars in `.env.local`. You can find the values for your sale on the [Echo founder dashboard](https://app.echo.xyz/founder). | ||
|
|
||
| ```sh | ||
| pnpm i | ||
| pnpm dev | ||
| ``` | ||
|
|
||
| The app will be available at `http://localhost:3000`. | ||
|
|
||
| ## What This Example Demonstrates | ||
|
|
||
| - **Provider setup** — configuring `SonarProvider` with wagmi and React Query | ||
| - **OAuth authentication with Sonar** — client-side flow using `useSonarAuth()` hook | ||
| - **Token management** — handled automatically by `@echoxyz/sonar-react` in browser storage | ||
| - **Entity state display** — prior to sale, list all user entities; during sale, show linked entity status | ||
| - **Pre-purchase checks** — validate eligibility before transactions using `useSonarPurchase()` | ||
| - **Purchase transactions** — generate permits and submit to the sale contract | ||
|
|
||
| ## Authentication Architecture | ||
|
|
||
| The `@echoxyz/sonar-react` library handles the complete OAuth flow client-side, storing tokens in browser storage: | ||
|
|
||
| ### OAuth Flow | ||
|
|
||
| ``` | ||
| ┌─────────┐ ┌─────────┐ ┌─────────┐ | ||
| │ Browser │ │ Sonar │ │ Echo │ | ||
| │ (React │ │ React │ │ OAuth │ | ||
| │ App) │ │ Library │ │ │ | ||
| └────┬────┘ └────┬────┘ └────┬────┘ | ||
| │ │ │ | ||
| │ 1. User clicks │ │ | ||
| │ "Connect with Sonar" │ │ | ||
| ├────────────────────────────>│ │ | ||
| │ │ │ | ||
| │ │ 2. Generate PKCE │ | ||
| │ │ params & store │ | ||
| │ │ in sessionStorage │ | ||
| │ │ │ | ||
| │ │ 3. Redirect via │ | ||
| │ │ window.location │ | ||
| │ │ │ | ||
| │ 4. Navigate to Echo OAuth │ │ | ||
| ├──────────────────────────────────────────────────────────>│ | ||
| │ │ │ | ||
| │ 5. User authenticates & authorizes │ | ||
| │ (interactive session) │ │ | ||
| │ │ │ | ||
| │ 6. Redirect to callback with auth code & state │ | ||
| │<──────────────────────────────────────────────────────────│ | ||
| │ │ │ | ||
| │ 7. Callback page calls │ │ | ||
| │ completeOAuth() │ │ | ||
| ├────────────────────────────>│ │ | ||
| │ │ │ | ||
| │ │ 8. Exchange code + │ | ||
| │ │ verifier for tokens │ | ||
| │ ├────────────────────────────>│ | ||
| │ │ │ | ||
| │ │ 9. Return tokens │ | ||
| │ │<────────────────────────────│ | ||
| │ │ │ | ||
| │ │ 10. Store tokens │ | ||
| │ │ in browser storage │ | ||
| │ │ │ | ||
| │ 11. authenticated = true │ │ | ||
| │<────────────────────────────│ │ | ||
| │ │ │ | ||
| ``` | ||
|
|
||
| ### API Requests | ||
|
|
||
| Once authenticated, Sonar API calls are made directly from the client using React hooks: | ||
|
|
||
| ``` | ||
| ┌─────────┐ ┌─────────┐ ┌─────────┐ | ||
| │ Browser │ │ Sonar │ │ Sonar │ | ||
| │ (React │ │ React │ │ API │ | ||
| │ App) │ │ Library │ │ │ | ||
| └────┬────┘ └────┬────┘ └────┬────┘ | ||
| │ │ │ | ||
| │ 1. useSonarEntities() │ │ | ||
| │ hook renders │ │ | ||
| ├────────────────────────────>│ │ | ||
| │ │ │ | ||
| │ │ 2. Get token from │ | ||
| │ │ browser storage │ | ||
| │ │ │ | ||
| │ │ 3. GET /entities │ | ||
| │ │ Authorization: Bearer... │ | ||
| │ ├────────────────────────────>│ | ||
| │ │ │ | ||
| │ │ 4. Response │ | ||
| │ │<────────────────────────────│ | ||
| │ │ │ | ||
| │ 5. Return entities │ │ | ||
| │ to component │ │ | ||
| │<────────────────────────────│ │ | ||
| │ │ │ | ||
| ``` | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| src/ | ||
| ├── components/ | ||
| │ ├── auth/ # Login/logout UI | ||
| │ ├── entity/ # Entity display components | ||
| │ ├── registration/ # Pre-sale entity list & eligibility | ||
| │ └── sale/ # Purchase flow UI | ||
| ├── pages/ | ||
| │ ├── Home.tsx # Main page (pre-sale & sale views) | ||
| │ └── OAuthCallback.tsx # OAuth callback handler | ||
| ├── config.ts # Environment configuration | ||
| ├── hooks.ts # Custom hooks (useSaleContract) | ||
| ├── Provider.tsx # SonarProvider, wagmi, React Query setup | ||
| └── main.tsx # App entry point | ||
| ``` | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems a bit too detailed