feat(agent): bring Agent Wallet to master (hidden in production)#2111
Open
MusabShakeel576 wants to merge 24 commits into
Open
feat(agent): bring Agent Wallet to master (hidden in production)#2111MusabShakeel576 wants to merge 24 commits into
MusabShakeel576 wants to merge 24 commits into
Conversation
…ration UX Wire the new /v1/agents/* backend endpoints into the UI: useAgentQuery, useProvisionAgent, useUpdateAgent, useAgentApiKeys, useGenerateAgentApiKey, useRevokeAgentApiKey. Add an Agent route accessible from the desktop nav that lets users provision an agent wallet, view the agent EOA / daily cap / allowlist, generate sk_solid_live_ API keys (one-time reveal), revoke keys, and copy a curl example + a Markdown system-prompt template designed to drop into Claude Desktop or ChatGPT custom GPTs. Surface agent activity types in the transaction-details map. Deposit flow is stubbed with a 'coming soon' toast — backend supports any path; client borrow-and-bridge wiring lands in a follow-up. (cherry picked from commit 99639c8)
…-chain balance - Move AgentSummary, AgentApiKeySummary, GenerateAgentApiKeyResponse from lib/api.ts to lib/types.ts. AgentSummary now only carries agentEoaAddress to match the simplified backend response. - Drop User.hasDepositedToAgentWallet — derived on the fly from the activity feed via useAgentDeposited (long-cached, one-way transition). - Drop useUpdateAgent (cap/allowlist removed from backend). - Add useAgentBalance: viem readContract on Base USDC for the agent EOA, refreshing every 60s. - Update Agent page copy from 'Idle USD principal stays in your soUSD vault and keeps earning' to 'Start earning yield on idle USDC in your agent wallet'. - Replace the cap/spent/allowlist counters card with a single 'USDC balance on Base' panel sourced from chain. (cherry picked from commit 32aed6b)
…rounded) (cherry picked from commit 2c09d65)
Use ' in copy that was tripping CI lint: - 'We'll create a new EOA…' (Agent setup CTA) - 'This is the only time you'll see the full key…' (reveal modal description) - 'I've saved it' (reveal modal confirmation button) (cherry picked from commit 16a1e8e)
- Reuse Base USDC address via getStargateToken(base.id) from
lib/utils/stargate.ts instead of duplicating the literal in
hooks/useAgent.ts. Keeps the canonical mapping single-sourced.
- Match useBalances resilience options on useAgentBalance: gcTime,
retry: 3 with exponential retryDelay, refetchOnWindowFocus,
refetchOnReconnect.
- Drop unused User.agentEoaAddress field from lib/types.ts — the
agent address is sourced via useAgentQuery, not user hydration.
- Remove dead { confirmed ? null : null } branch and the unused
confirmed state from ApiKeyRevealModal.tsx.
- Switch IntegrationSnippet's clipboard call from a dynamic
import('expo-clipboard') inside the handler to a static import,
matching the canonical pattern in components/CopyToClipboard.tsx.
- Re-route AgentApiKeySummary import in ApiKeyList.tsx from @/lib/api
(where it no longer lives) to @/lib/types.
(cherry picked from commit 0f17a9b)
- Register agent/index in the protected Stack with headerShown: false so the default 'agent/index' header strip stops rendering above the page (matches every other route in (protected)). - Restyle the 'Set up your agent' empty state to mirror the /card/pending box (rounded-2xl, border-white/5, bg-[#1C1C1C], padded px-6 pb-8 pt-10, centered title + description). Skipping the image per the screenshot direction; full-width primary CTA at the bottom. (cherry picked from commit 73f4f31)
…eady (cherry picked from commit e2b3f86)
- Drop the Agent Wallet heading + description from the empty state so the setup card stands alone (only render them once provisioned). - Narrow the empty state container to max-w-lg / pt-8 to mirror /card/pending; keep max-w-3xl + py-6/md:py-10 once provisioned. - Reserve a 268px-tall placeholder block above the title — same height as /card/pending's card-fade illustration, so the layout doesn't jump when we swap in the real artwork later. - Rename CTA + box title from 'Set up Agent' / 'Set up your agent' to 'Set up your Agent Wallet'. Provisioning creates the EOA itself, the Turnkey user, and the policy in one step — there's no separate 'agent' without a wallet, so the longer name is more accurate. (cherry picked from commit c417daf)
Hit /agent?status=loading | not_provisioned | provisioned | deposited to force the page into a specific branch without going through real provisioning + activity flow. Useful for visual QA on the empty state, provisioned state, and the Switch's deposited variant. - Override is parsed via useLocalSearchParams and gated on !isProduction — the param is silently ignored on prod builds. - Live useAgent* hooks keep firing under the override so toggling the param off cleanly reverts to real data without a remount. - 'provisioned' / 'deposited' supply a stub agent EOA, a fake 2.34 USDC balance, and (for 'deposited') flip the Human/Agent Switch to the right side. (cherry picked from commit fb2f4e5)
UI restyle informed by the screenshot direction: - Move Generate API Key + Deposit out of inline cards into the page header. flex-row justify-between with title block on the left and buttons on the right (desktop), matching /card/details:352. On mobile the header collapses to title above + circular action buttons (a green Deposit + dark Generate Key) in a row, mirroring the mobile hero pattern. - Drop the Human/Agent toggle entirely. The deposited bool is no longer surfaced in the UI. - Wallet + API key boxes now sit side-by-side on desktop (flex-row, flex-1 each) and stack on mobile (flex-col). 'How to use' lives below as a single full-width box. - All three boxes use the same rounded-2xl bg-[#1C1C1C] base as the setup card. Inner content stays left-aligned per the direction; copy + balance live inside the wallet card. - Strip every border-* class. Sub-elements (api key rows, snippet block, reveal modal key block) now use rounded-xl bg-[#262626] instead of bordered backgrounds. - All ActivityIndicators on the agent surface explicitly color='white' to drop the platform-default tinted spinner. - Bump the provisioned-state max-width from max-w-3xl to max-w-5xl so the side-by-side cards have room to breathe. - Deposit button still no-ops to a clarifying toast — the actual flow is the borrow-against-savings clone (per the original plan U3) and is being tracked as a follow-up. (cherry picked from commit 94bb265)
…lance gradient Borrow flow: - Extract the heavy lifting of useBorrowAndDepositToCard into a shared inner async helper at lib/utils/borrowAndBridge.ts. The function takes destinationAddress + destinationChainId/Key + destinationToken so the same on-chain transaction batch (approve soUSD → Aave supply → borrow USDC.e → approve CardDepositManager → BridgePaymaster callWithValue) handles any Stargate destination. - useBorrowAndDepositToCard becomes a thin wrapper that resolves the card-funding address and forwards to the helper. Existing tracking events + Sentry breadcrumbs preserved. - New useBorrowAndDepositToAgent wraps the same helper with the agent EOA + base.id + Stargate Base USDC, and emits AGENT_WALLET_DEPOSIT activities. - The CardDepositManager forwards regardless of receiver because isWhitelistEnabled is off in prod (verified: no caller of authorizeCards or setWhitelistEnabled in this repo or boring-vault), so we reuse the existing manager + sponsorship path on BridgePaymaster — no new contract, no new sponsor tx. Modal: - New AgentDepositModal: amount input, live borrow position (useAaveBorrowPosition), Max button capped at totalSupplied * LTV - totalBorrowed, brand-variant Borrow CTA. On submit invokes the new hook; toast on success/failure; modal closes on success. - Bound to the Agent page Deposit button (replaces the 'coming soon' toast). Mobile circular Deposit button opens the same modal. Page header: - Copy prompt button moved out of IntegrationSnippet and into the page-header button group, alongside Generate API key + Deposit. Uses the same secondary 'h-12 rounded-xl bg-[#303030] px-6' styling as Generate API key, with a FileText icon. Mobile gets a third dark CircleAction labelled 'Prompt'. - IntegrationSnippet now only renders the curl example + copy affordance and points users at the header for the prompt template. Balance card: - Replace the bg-[#1C1C1C] balance box with a /card/details-style SpendingBalanceCard: rounded-[20px], green LinearGradient overlay (rgba(104,216,82,…)), 50px USDC balance up top, 'Earning yield on idle USDC' caption underneath. Address moves into the API keys card so the balance card stays a hero panel. (cherry picked from commit 838d335)
…lance card
Modal:
- Rebuild AgentDepositModal on top of ResponsiveModal with the same
containerClassName='min-h-[42rem] overflow-y-auto flex-1' that the
card deposit uses, so size + animation + header back-button behavior
match. Inner content adopts CardDepositInternalForm primitives:
bg-accent rounded-2xl px-5 py-{3,4} blocks, 'Amount to borrow' label
+ USDC token icon + 2xl input, 'Available to borrow / Max' row, and
a small position breakdown (Currently borrowed, Supplied as
collateral). Brand-variant Borrow CTA at the bottom.
Provisioned page:
- Bump max-width from max-w-5xl to max-w-7xl to match /card/details:150.
- Center the desktop header (title block + button row stacked, both
items-center) instead of the previous flex-row justify-between.
- Bump page-level gap from gap-6 to gap-10 (gap-12 on md) so the
header breathes above the boxes.
- Add max-w-xl to IntegrationSnippet's description so the line length
isn't card-wide on desktop.
Balance card:
- Switch the LinearGradient palette from green
rgba(104,216,82,…) to blue rgba(74,144,226,1) → rgba(120,192,250,0.55)
so the agent page reads distinctly from the green card surface,
purple savings, and yellow rewards.
- Rename label from 'USDC balance on Base' to 'Spendable balance' to
match /card/details copy.
- Add gap-12 between the balance and 'Earning' rows so the two blocks
are visually separated, with min-h-[260px] floor to match the card
card's minimum hero height.
(cherry picked from commit 69e69a4)
Revert the items-center stack to the original layout (title left, buttons right) with mx-auto on the row so the whole header still sits centered within the max-w-7xl page wrapper. (cherry picked from commit fb607ef)
(cherry picked from commit 913b92d)
…posit Replace the bespoke amount-input + position-summary modal content with a direct clone of the card form's BORROW path: - BorrowSlider from components/Card/BorrowSlider for the amount input (slider + decimal input fused; min 0, max = totalSupplied * 0.69 - totalBorrowed, matching the card flow's CardDepositInternalForm:706). - TokenDetails block with Borrow rate (from useAaveBorrowPosition.borrowAPY) and Collateral Required (live computed from slider value), plus the same 'Use your soUSD as collateral … Learn more.' helper paragraph used on /card/details. - Bottom CTA reduced to a single brand-variant 'Deposit' button matching CardDepositInternalForm:548 — same h-12 rounded-2xl, ActivityIndicator swap when submitting. Page header: - Drop the wrapper's mx-auto (the page-level mx-auto on the max-w-7xl container already centers it). Switch items-end to items-center so the buttons align with the title text baseline rather than its descender. Balance gradient: - First stop now rgba(4, 96, 203, 1) per the latest spec; second stop unchanged. (cherry picked from commit 2fbc21d)
Replaces the single POST /v1/agents/provision call with the four-step init → walletAccount → user → policy chain. We mint (or refresh) a Turnkey read-write session up front with one passkey gesture, then each step silently API-key-stamps the unsigned activity body the backend hands us and posts the signed envelope back. Backend relays the signed bytes to Turnkey verbatim, so the stamp still validates. This fixes the ORGANIZATION_MISMATCH error users hit on Set up Agent — the parent-org admin can't sign writes against existing sub-orgs. (cherry picked from commit 97a4901)
SignedTurnkeyRequest, ProvisioningActivity, ProvisioningInitResponse, and ProvisioningStepInput were declared inline next to the fetch helpers; move them to lib/types.ts to match the convention used by the rest of the file. useAgent.ts imports SignedTurnkeyRequest from there directly now instead of re-exporting via api.ts. (cherry picked from commit 7111e38)
Two staging failures fixed: - loginWithPasskey now passes organizationId: subOrganizationId so the session API key is minted on the user's sub-org. Without this Turnkey rejects sub-org activities with PUBLIC_KEY_NOT_FOUND. - If init returns an agentEoaAddress, the user already had a derived wallet account from a prior failed attempt. We skip the createWalletAccounts stamp and use init's `activity` (createUsers body) directly. Also: ensureSession now invalidates a cached session if its organizationId doesn't match the user's sub-org, since switching scopes requires a fresh login. (cherry picked from commit 952e0f4)
Match the rest of the agent flow: ResponsiveModal wrapper for mobile/web parity, brand-variant button at h-14 rounded-2xl like the email-OTP and swap modals. (cherry picked from commit 467be61)
Prompt template: - Endpoint URL is built from EXPO_PUBLIC_FLASH_API_BASE_URL with the required `/accounts/v1/...` path so AI tools call the live route instead of the legacy `/v1/...` (the latter 404s on accounts-qa). - Drop MVP-out-of-scope language: no per-tx caps, no daily caps, no recipient allowlist (none of these are enforced server-side anymore). - Explicit safety paragraph: pasting the live key into Claude Desktop / ChatGPT is fine — the key only authorizes USDC payments out of this one agent wallet, gated by a Turnkey policy. - First-turn behavior: the model should respond in 3-4 sentences, confirm setup, and suggest exactly 3 x402 stores/APIs relevant to the user as a "what to try first" prompt. No technical detail. Deposit modal: - Source picker (web only — thirdweb's connector flow is web-only), branching into the existing borrow-against-savings flow or a new external-wallet flow. - New AgentDepositExternalForm: connect via thirdweb, switch chain to Base, transfer USDC directly from the connected wallet to the agent EOA. Logs an AGENT_WALLET_DEPOSIT activity. No Stargate, no yield — the copy makes that explicit. Also: IntegrationSnippet now uses the same dynamic base URL. (cherry picked from commit 9c3c60d)
…or-key first External deposit: - Drop the thirdweb connect-wallet flow. The new screen reuses DepositPublicAddress to render the agent EOA as a copyable string + QR code, scoped to Base USDC. Works on both web and native. - Removes the ~200-line transfer/activity-creation code and the thirdweb dependency for this surface. Borrow form: - Yellow warning banner above the slider when isProduction is false: the soUSD/Aave market isn't deployed in QA so the borrow flow can't actually execute. Points users at the external-wallet option for testing. Prompt template: - New first-turn step zero: if the AI doesn't have SOLID_API_KEY yet, it must ask the user to paste one (and tell them where to generate it — the Agent tab) before doing anything else. (cherry picked from commit 500ee5e)
…reen Mirror the card deposit modal's source selector. The agent deposit modal is now a single screen with a 'From' dropdown at the top (Borrow against Savings / External Wallet) and the matching form rendered inline below. Removes the prior options-step indirection, the back-button bookkeeping, and the per-option descriptions. - Web: real DropdownMenu (radix) — same -mt-4 rounded-b-2xl pattern. - Native: inline expanding section (Pressable + isOpen) — same as the card flow's SourceSelectorNative. - AgentDepositBorrowForm extracted into its own file for symmetry with AgentDepositExternalForm. (cherry picked from commit 106e1ca)
Single-network surface (Base USDC only); the link sent users to a generic supported-networks doc that doesn't apply here. The Base chain badge + 'Send only USDC on Base' warning carry the right scope. (cherry picked from commit a4dcd98)
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
Cherry-picks the Agent Wallet feature from
qaonto a branch offmaster, and hides the Agent tab in production until the feature is released.Task 1 — Cherry-pick Agent Wallet from
qaCherry-picked all 23 agent commits (the
feat/fix/style/refactor(agent)series fromclaude/agent-yield-payments-b4DMj) in order, since the feature landed onqaincrementally rather than as a single merge.masterpreviously had no agent code.qabyte-for-byte):app/(protected)/agent/index.tsx,components/Agent/*,hooks/useAgent.ts,hooks/useBorrowAndDepositToAgent.ts,constants/agentPromptTemplate.ts,lib/utils/borrowAndBridge.ts.mastercontent and the agent additions:constants/path.ts,constants/transaction.ts,lib/types.ts,app/(protected)/_layout.tsx,lib/api.ts,hooks/useBorrowAndDepositToCard.ts.useBorrowAndDepositToCard.ts,lib/api.ts) matchesqaexactly so the existing card flow is unaffected. All local imports resolve onmaster(borrow/deposit infra, ABIs, hooks already present).Task 2 — Hide Agent tab in production
hooks/useNav.tsnow omits the Agent entry from the nav menu whenisProduction, reusing the existingisProductionflag from@/lib/config. The agent route still exists; only the tab is hidden in prod.Notes
node_modulesisn't available in this environment, solint/typecheck were not run locally — please let CI validate.https://claude.ai/code/session_01Hzy5zskEvLozGA6ih1Bhty