-
Notifications
You must be signed in to change notification settings - Fork 0
ui: add components for Venue Management and Bot assignment to Venues #94
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
ui: add components for Venue Management and Bot assignment to Venues #94
Conversation
- Add venue-related types from schema to api.ts - Add custom UI types: VenueFormData, VenueWithAssignments, VenueAssignmentWithBot, BotWithVenue - Create venue-utils.ts with validation and normalization functions - Add API_ENDPOINTS constants for mainnet/testnet - Implement wallet address truncation for UI display
- Create venue-api.ts with complete API client for venue operations - Implement fetchVenues, upsertVenue, deleteVenue endpoints - Add venue assignment operations: fetch, assign, unassign - Add bot venue operations: fetchBotVenues - All endpoints use buildOpsApiUrl with credentials include
- Add shadcn-style table component with all table primitives - Create Settings page with tabbed interface for venues and bot assignments - Integrate VenueManagement and BotAssignmentManager in settings tabs - Add back navigation support for settings page
- Update VenueManagement to use fetchVenues, upsertVenue, deleteVenue - Update VenueAssignments to use real assignment API endpoints - Update BotList to use fetchBotVenues and assignBotToVenue - Fix sonner import errors in all venue components - Remove all mockApiCall functions - Use buildOpsApiUrl with credentials include for all API calls
- Replace single hyperliquid config with venues array - Integrate VenueManagement component in step 3 - Update SetupData interface to use VaultVenueSecret[] for venues - Update buildSecretsBundle to use venues array from setup data - Add venue validation requiring at least one venue before continuing - Users can now configure multiple wallets during initial setup
- Add Settings button to dashboard header with gear icon - Add showSettings state to toggle between dashboard and settings - Lazy load Settings component for code splitting - Add Settings icon from lucide-react - Settings page includes back button to return to dashboard - Maintain Toaster across both views
- Add Execution Venue card to order detail dialog - Display venue_id and wallet address from order identifiers - Show truncated wallet address with copy-to-clipboard button - Display full wallet address for reference - Add Wallet icon from lucide-react - Use truncateWalletAddress utility for consistent formatting
- Add type-only imports for all component type definitions to comply with verbatimModuleSyntax - Fix validation error handling in VenueForm (validation functions return string | null, not objects) - Add isCustom parameter to validateApiUrl call in VenueForm - Fix isDuplicateWallet function call with correct parameters (VenueRecord[] instead of string[]) - Rename truncateAddress to truncateWalletAddress in VenueList and VenueDetail - Update ConfirmationStep to use new SetupData structure with venues array - Add missing dropdown-menu UI component - Add null safety check for venue.api_url in ConfirmationStep All TypeScript errors are now resolved and npx tsc --noEmit passes successfully.
- Remove unused 'loading' parameter from BotAssignmentDialog - Remove unused imports in BotAssignmentManager (useState, Tabs components) - Remove unused handleVenuesLoaded function in Settings - Remove unused error parameter in VenueAssignments catch block - Remove unused truncateWalletAddress import in VenueDetail - Change 'let' to 'const' for non-reassigned variables in VenueManagement - Refactor venue deletion to avoid mutation and properly use const - Remove unused 'index' parameter in ConfirmationStep map All ESLint and TypeScript checks now pass successfully.
Add onVenuesLoaded callback to VenueManagement component that is called after venues are loaded from the API in settings context. Use this callback in Settings component to populate the venues state, which is then passed to BotAssignmentManager. This fixes the issue where the Bot Assignments tab would always show "no wallets available" even when wallets existed, because the venues state was never populated. - Add onVenuesLoaded prop to VenueManagementProps - Call onVenuesLoaded after fetching and setting venues - Implement handleVenuesLoaded in Settings to update local state - Pass onVenuesLoaded callback to VenueManagement component
…upport-for-hyperliquid' into claude/investigate-hyperliquid-multi-wallet-011CUw4TittMwEzSwEkX1xB6
Implement client-side vault update functionality to properly persist venue credentials (including private keys) when adding, editing, or deleting wallets in the Settings UI. ## New Files - `vault-utils.ts`: WebAuthn PRF-based encryption/decryption utilities for vault payload operations ## API Updates (venue-api.ts) - Add `fetchVaultPayload()`: GET /vault/payload - Add `updateVaultPayload()`: PUT /vault/payload - Import VaultEncryptedPayload and VaultSecretsBundle types ## VenueManagement Component Updates - Add `vaultNeedsReseal` state to track when vault needs re-seal - Add `updateVaultWithModifiedVenues()` helper that: - Fetches current encrypted vault payload - Decrypts using WebAuthn PRF - Applies venue modifications via callback - Re-encrypts payload - Sends to server for persistence - Update `handleAddVenue()` in settings context to use vault update - Update `handleEditVenue()` in settings context to use vault update - Update `handleDeleteVenue()` in settings context to use vault update - Add blue info banner when vault needs reseal with instructions ## How It Works (Settings Context) 1. User adds/edits/deletes a wallet in Settings UI 2. Component fetches encrypted vault payload from server 3. Decrypts payload using WebAuthn PRF to get current secrets 4. Modifies the venues array (add/edit/delete) 5. Re-encrypts entire payload with updated venues 6. Sends both encrypted and decrypted payloads to server 7. Server validates decrypted payload before persisting encrypted version 8. Shows banner: "Vault changes saved. Seal and re-unseal to activate." 9. User must seal and re-unseal vault for changes to take effect ## Security Notes - Private keys are never exposed via public API endpoints - All venue credentials remain in encrypted vault payload - WebAuthn PRF ensures only authorized user can decrypt/encrypt - Server validates payload integrity before persisting Setup wizard context remains unchanged (uses local state, no vault ops). All TypeScript and ESLint checks pass.
The previous implementation incorrectly attempted to use WebAuthn PRF for encryption/decryption, but the actual system uses standard AES-GCM with a randomly generated key stored in prf_params.key. Changes: - Rewrite vault-utils.ts to match Login.tsx and SetupWizard.tsx patterns - Extract encryption key from payload.prf_params.key (base64url encoded) - Reuse the same encryption key when updating vault payload - Add base64url encoding/decoding helpers - Update encryptVaultPayload signature to accept originalPayload parameter - Update VenueManagement.tsx to pass original payload to encryptVaultPayload This fixes the WebAuthn implementation issues identified in code review by removing the incorrect WebAuthn PRF usage entirely and using the correct AES-GCM encryption approach that matches the rest of the codebase.
Add fallback support for legacy single-venue vault payloads that use HYPERLIQUID_WALLET, HYPERLIQUID_PRIVATE_KEY, and HYPERLIQUID_API_URL fields instead of the modern venues array. This prevents existing deployments from failing with ErrPrimaryVenueRequired when unsealing vaults that were created before the multi-venue support. Changes: - Add legacy field parsing to wireData struct - Convert legacy fields to a single venue entry if venues array is empty - Set converted venue as primary with ID "hyperliquid-legacy" - Default to https://api.hyperliquid.xyz if API URL not specified The system does not require active migration - legacy payloads continue to work as-is. Users can update to the modern format via Settings UI when convenient.
This reverts commit b306d71.
Allow vault payloads with empty venues array without erroring out. If venues are present, they are still validated for correctness (unique IDs, valid wallet/key format, exactly one primary).
…lti-wallet-011CUw4TittMwEzSwEkX1xB6 refactor(hyperliquid): simplify venue handling to single default wallet | Area | Change | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Vault validation | `Data.Validate` now requires `secrets.venues` to be present, returning an explicit error when empty. | | Setup wizard | Replaced multi-venue setup with a single `hyperliquid` config (`apiUrl`, `wallet`, `privateKey`) and map it to one default `hyperliquid:default` venue in `secrets.venues`. | | Web UI header | Removed Settings page toggle and button from `App.tsx`, leaving just the main title and logo. | | Venue / bot UI | Removed venue and bot assignment management components (wallets, assignments, lists, detail views). | | Order detail UI | Dropped the “Execution Venue” card from `OrderDetailDialog` (no wallet/venue info shown there anymore). | | Types & utilities | Removed venue-related types (`VaultVenueSecret`, `VenueRecord`, etc.) and helpers (`venue-*`, `vault-utils`, `venue-api`). | | UI primitives | Removed local `checkbox`, `dropdown-menu`, `select`, and `table` wrappers that were only used by the deleted venue UI. | | Docs | Trimmed `AGENTS.md` by removing the “Missing elements” / shadcn install note. | | Dependencies | Aligned Radix versions: downgraded `@radix-ui/react-checkbox` and `@radix-ui/react-select` to match the used shadcn presets. |
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.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const venues = await fetchVenues(); | ||
|
|
||
| // Load assignment counts for each venue | ||
| const venuesWithCounts = await Promise.all( | ||
| venues.map(async (venue) => { | ||
| try { | ||
| const assignments = await fetchVenueAssignments(venue.venue_id); | ||
| return { | ||
| ...venue, | ||
| assignmentCount: assignments.length, | ||
| }; | ||
| } catch { | ||
| return { ...venue, assignmentCount: 0 }; | ||
| } | ||
| }) | ||
| ); | ||
|
|
||
| setVenues(venuesWithCounts); | ||
| onVenuesLoaded?.(venuesWithCounts); | ||
| } catch (error) { |
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.
Preserve primary wallet flag when populating settings state
The settings view builds its wallet list from fetchVenues() in loadVenuesFromAPI, but the returned records only expose raw flags; the code never derives isPrimary when storing the list (setVenues(venuesWithCounts)). Downstream actions such as edit and delete rely on venue.isPrimary (e.g. promoting a new primary on delete or pre-checking the form), so every venue is treated as non‑primary. Deleting or editing the real primary wallet therefore sends a payload where no venue is marked primary and the backend’s validation (Validate: “invalid payload: no primary venue found”) rejects the request. The UI surfaces “Failed to delete/update wallet” without guidance, leaving the user unable to manage the primary wallet. Consider decoding flags.is_primary (or loading the vault payload) before assigning isPrimary so a single primary is always preserved.
Useful? React with 👍 / 👎.
The settings view builds its wallet list from fetchVenues() in loadVenuesFromAPI, but the returned VenueRecord objects store the primary flag inside venue.flags.is_primary. The code was not extracting this value when populating the state, so downstream actions (edit, delete) that rely on venue.isPrimary would fail backend validation when no primary venue was marked. This fix decodes flags.is_primary when mapping venues so the isPrimary property is correctly set on VenueWithAssignments objects, ensuring that exactly one primary venue is always preserved during updates. Fixes the "invalid payload: no primary venue found" validation error when editing or deleting the primary wallet.
…CUxwgEqEVqUuf7yZnBxLd fix(ui): extract isPrimary flag from venue.flags in settings view
ce8fb0b
into
codex/investigate-multi-wallet-support-for-hyperliquid
No description provided.