diff --git a/.tickets/tic-32f9.md b/.tickets/tic-32f9.md
new file mode 100644
index 00000000..e0f26e01
--- /dev/null
+++ b/.tickets/tic-32f9.md
@@ -0,0 +1,43 @@
+---
+id: tic-32f9
+status: open
+type: bug
+priority: 1
+assignee: Jibles
+created: 2026-03-19T09:48:16.870745261Z
+---
+# USDC swap reverts after approval on Arbitrum
+
+## Summary
+
+Swapping USDC -> ETH on Arbitrum fails at the "Sign swap transaction" step after the approval step succeeds. ETH -> USDC swaps work fine.
+
+## Steps to Reproduce
+
+1. Connect with embedded wallet (Dynamic) on Arbitrum
+2. Ask agent: "Swap 1 USDC to ETH on Arbitrum"
+3. Confirm the Dynamic transaction modal
+4. Observe: steps 1-3 (Getting swap quote, Switch to arbitrum, Approve token spending) succeed
+5. Step 4 (Sign swap transaction) fails
+
+## Error
+
+`Execution failed: Swap failed: Transaction will revert: Execution reverted for an unknown reason.`
+
+## Expected Behavior
+
+Swap should execute successfully like ETH -> USDC does.
+
+## Notes
+
+- The approval tx goes through on-chain, so the user's USDC allowance is set but the trade never executes
+- This appears to be specific to selling ERC-20 tokens (native ETH sells work)
+- Could be a slippage, routing, or contract interaction issue
+- Tested with wallet `0xD32Bb617c25f33563817A58004F2A441Ff8660F3` holding ~2.32 USDC on Arbitrum
+
+## Acceptance Criteria
+
+- [ ] USDC -> ETH swap executes successfully on Arbitrum
+- [ ] Other ERC-20 -> native token swaps work
+- [ ] No orphaned approvals left on failed swaps
+
diff --git a/.tickets/tic-616a.md b/.tickets/tic-616a.md
new file mode 100644
index 00000000..d356c1c1
--- /dev/null
+++ b/.tickets/tic-616a.md
@@ -0,0 +1,39 @@
+---
+id: tic-616a
+status: open
+type: bug
+priority: 2
+assignee: Jibles
+created: 2026-03-19T09:48:28.499128674Z
+---
+# Dollar sign stripped from chat input messages
+
+## Summary
+
+The `$` character is silently stripped from chat messages when sent. Typing `$2 worth of ETH` results in the message appearing as `worth of ETH` — the `$2` portion is completely removed.
+
+## Impact
+
+This makes the USD-based swap tool (`initiateSwapUsdTool`) effectively unusable, since users cannot specify dollar amounts. The agent then misinterprets the message (e.g., "1 worth is ambiguous").
+
+## Steps to Reproduce
+
+1. Connect wallet and open a new chat
+2. Type: `Swap $2 worth of ETH to USDC on Arbitrum`
+3. Send the message
+4. Observe: the message bubble shows `Swap worth of ETH to USDC on Arbitrum` — `$2` is gone
+
+## Expected Behavior
+
+The `$` character should be preserved in messages. Dollar amounts are a core part of the crypto trading UX.
+
+## Likely Location
+
+Chat input component text handling — possibly overzealous sanitization or a template literal issue stripping `$`.
+
+## Acceptance Criteria
+
+- [ ] Dollar sign characters are preserved in sent messages
+- [ ] USD-based swap requests like 'Swap $2 of ETH to USDC' work correctly
+- [ ] No XSS or injection regressions from allowing $
+
diff --git a/.tickets/tic-78e5.md b/.tickets/tic-78e5.md
new file mode 100644
index 00000000..aa80c0c2
--- /dev/null
+++ b/.tickets/tic-78e5.md
@@ -0,0 +1,33 @@
+---
+id: tic-78e5
+status: open
+type: feature
+priority: 3
+assignee: Jibles
+created: 2026-03-19T09:48:42.234098894Z
+---
+# External address lookup does not support ENS names
+
+## Summary
+
+The `lookupExternalAddressTool` only accepts raw hex Ethereum addresses. ENS names like `vitalik.eth` are rejected with "invalid format for direct lookup."
+
+## Current Behavior
+
+Asking "Look up the balance of vitalik.eth" returns:
+> The address "vitalik.eth" couldn't be resolved (invalid format for direct lookup). Provide the resolved Ethereum address (e.g., 0xd8dA6BF...) to check its portfolio balance.
+
+## Expected Behavior
+
+The tool should resolve ENS names to addresses before performing the lookup, or the agent should resolve ENS first and then call the tool with the hex address.
+
+## Notes
+
+- This is a common user expectation — ENS names are widely used
+- Resolution could happen server-side in the tool or client-side before the tool call
+
+## Acceptance Criteria
+
+- [ ] ENS names (e.g., vitalik.eth) resolve to addresses and return balances
+- [ ] Invalid ENS names return a clear error message
+
diff --git a/.tickets/tic-93f0.md b/.tickets/tic-93f0.md
new file mode 100644
index 00000000..ba7f4a4a
--- /dev/null
+++ b/.tickets/tic-93f0.md
@@ -0,0 +1,34 @@
+---
+id: tic-93f0
+status: open
+type: chore
+priority: 4
+assignee: Jibles
+created: 2026-03-19T09:49:10.195588513Z
+---
+# Generic error messages for backend failures lack actionable detail
+
+## Summary
+
+When the backend API is unavailable, multiple tools show one of two generic error messages with no actionable detail:
+
+1. Portfolio tool: "Failed to fetch portfolio details" (red text)
+2. All other wallet tools: "Something went wrong — The service is temporarily unavailable. Please try again." (red error banner)
+
+Neither message helps the user understand what's wrong or what to do beyond "try again."
+
+## Affected Tools
+
+All wallet-dependent tools when backend is down: portfolioTool, receiveTool, transactionHistoryTool, and likely others.
+
+## Suggested Improvement
+
+- Differentiate between network errors (backend unreachable), auth errors (session expired), and API errors (bad request)
+- For backend-down scenarios, surface something like "Unable to reach the ShapeShift API. Check your connection or try again in a moment."
+- Consider adding retry logic for transient failures
+
+## Acceptance Criteria
+
+- [ ] Error messages distinguish between different failure types
+- [ ] Users get actionable guidance when errors occur
+
diff --git a/.tickets/tic-fc5f.md b/.tickets/tic-fc5f.md
new file mode 100644
index 00000000..e3689eef
--- /dev/null
+++ b/.tickets/tic-fc5f.md
@@ -0,0 +1,36 @@
+---
+id: tic-fc5f
+status: open
+type: bug
+priority: 3
+assignee: Jibles
+created: 2026-03-19T09:48:57.995716495Z
+---
+# Portfolio side panel shows stale 'No assets found' state
+
+## Summary
+
+The portfolio side panel (opened by clicking the wallet address button in the nav bar) shows "\$0.00" and "No assets found — Connect a wallet to view your portfolio" even when the wallet IS connected and the portfolio tool returns real balances (\$8.80 USDC + ETH on Arbitrum).
+
+## Additional Issue
+
+The panel occasionally auto-opens during interactions (e.g., when scrolling, or when the wallet button region is inadvertently activated), stealing focus from the chat. This is disruptive during conversations with the agent.
+
+## Steps to Reproduce
+
+1. Connect embedded wallet (0xD32B...60F3)
+2. Click the wallet address button in the top-right nav
+3. Observe: panel shows \$0.00 and "No assets found"
+4. Ask the agent "What is my portfolio balance?"
+5. Agent correctly returns \$8.80 — the panel data is stale/wrong
+
+## Expected Behavior
+
+- Panel should show real portfolio balances matching what the portfolio tool returns
+- Panel should not auto-open unexpectedly
+
+## Acceptance Criteria
+
+- [ ] Portfolio panel shows correct balances when wallet is connected
+- [ ] Panel does not auto-open unexpectedly during chat interactions
+
diff --git a/apps/agentic-chat/src/components/Portfolio/PortfolioAssetList.tsx b/apps/agentic-chat/src/components/Portfolio/PortfolioAssetList.tsx
index e644ef3d..f48e7f93 100644
--- a/apps/agentic-chat/src/components/Portfolio/PortfolioAssetList.tsx
+++ b/apps/agentic-chat/src/components/Portfolio/PortfolioAssetList.tsx
@@ -1,3 +1,5 @@
+import { useDynamicContext } from '@dynamic-labs/sdk-react-core'
+import { Loader2, RefreshCw } from 'lucide-react'
import { useMemo } from 'react'
import { Virtuoso } from 'react-virtuoso'
@@ -25,11 +27,20 @@ export function AssetListSkeleton({ rows = 5 }: { rows?: number }) {
}
export function PortfolioAssetList() {
- const { assets, isLoading } = usePortfolioQuery()
+ const { primaryWallet } = useDynamicContext()
+ const { assets, isLoading, isFetching } = usePortfolioQuery()
const groupedAssets = useMemo(() => groupPortfolioAssets(assets), [assets])
if (isLoading) {
- return