Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
a0618c1
fix: copy patches dir in public-api Dockerfile for pnpm install
0xApotheosis Mar 4, 2026
473f2d3
fix: add .railwayignore to reduce snapshot size for public-api deploys
0xApotheosis Mar 4, 2026
dc3c2b0
Revert "fix: add .railwayignore to reduce snapshot size for public-ap…
0xApotheosis Mar 5, 2026
eb5562c
Revert "fix: copy patches dir in public-api Dockerfile for pnpm install"
0xApotheosis Mar 5, 2026
b95adf5
fix: unrug Railway CI - copy patches dir and add .railwayignore (#12099)
0xApotheosis Mar 5, 2026
3c56acf
fix: use copy package-import-method in Docker to avoid pnpm ENOENT (#…
0xApotheosis Mar 5, 2026
b4b0ade
feat: speed up stuck btc transactions via rbf (#11885)
gomes-bot Mar 5, 2026
11e7ca7
Merge branch 'main' into develop
0xApotheosis Mar 5, 2026
702ba59
fix: railway build with pnpm (#12107)
kaladinlight Mar 6, 2026
ff51d45
feat: thorchain solana lp integration (#12037)
gomesalexandre Mar 9, 2026
a0e5c28
fix: narrow YieldExplainers action prop type to remove unused claim v…
NeOMakinG Mar 9, 2026
455bdca
fix: always refresh account balances after swap completion (#12106)
NeOMakinG Mar 9, 2026
32716ef
chore: unify claude and codex instruction entrypoints (#12119)
gomesalexandre Mar 9, 2026
5347030
feat: idempotent release script state machine (#12110)
gomesalexandre Mar 9, 2026
262b639
feat: bebop solana swapper take 2 (#12111)
gomesalexandre Mar 9, 2026
5481993
chore: remove unused @chainflip/rpc and @chainflip/extrinsics deps (#…
gomesalexandre Mar 9, 2026
ddc7a39
fix: bump Claude max-turns from 3 to 10 in release script (#12129)
0xApotheosis Mar 10, 2026
b527872
fix: bebop solana signing + thorchain solana lp compute budget (#12131)
gomesalexandre Mar 10, 2026
2c4d0b6
fix: root cause of pnpm docker build issues (take again...) (#12126)
kaladinlight Mar 10, 2026
ead6a6f
feat: add native QR scanner support for mobile app (#11516)
0xApotheosis Mar 11, 2026
160813f
feat: b2b affiliate tracking system (#12012)
NeOMakinG Mar 11, 2026
a6c1d54
fix: bebop solana signing + reject amm-routed quotes (#12134)
gomesalexandre Mar 11, 2026
2cf13ce
feat: chainflip lending - product docs (#12124)
gomesalexandre Mar 11, 2026
0752f33
fix(affiliate-dashboard): add default API_URL to prevent 403 errors (…
NeOMakinG Mar 11, 2026
189e2be
feat: portless support for stable dev server URLs (#12130)
gomesalexandre Mar 11, 2026
e49b848
fix: bebop solana ghost tx + malformed amm routes (#12148)
gomesalexandre Mar 12, 2026
4f88859
fix: chainflip lending ui fixes and polish
gomesalexandre Mar 12, 2026
8d4db22
feat: wire debridge to 9 additional evm chains
gomesalexandre Mar 12, 2026
948a254
feat: wire cow swap to plasma, linea, and ink
gomesalexandre Mar 12, 2026
1b148c0
feat: wire across to scroll and megaeth
gomesalexandre Mar 12, 2026
f06c48e
feat: add wbtc.eth, usdt.sol, usdt.arb to chainflip supported assets …
gomesalexandre Mar 12, 2026
6a20c43
feat: metamask native multichain
gomesalexandre Mar 12, 2026
812f93e
feat: jito block engine for solana mev protection and bundle splittin…
gomesalexandre Mar 12, 2026
f6f3ae0
feat: chainflip lending ui fixes and polish (#12153)
gomesalexandre Mar 12, 2026
8bbcd27
chore(deps): bump axios from 0.21.4 to 0.30.3 (#11967)
dependabot[bot] Mar 12, 2026
ff0aa68
fix: attempt at fixing rfox apy since usdc change (#12120)
NeOMakinG Mar 13, 2026
15c8ada
Merge remote-tracking branch 'origin/main' into develop
gomesalexandre Mar 13, 2026
7d598bb
fix: bump NativeQrScanner minimum version to 3.7.2 (#12173)
0xApotheosis Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 50 additions & 19 deletions .claude/skills/qabot/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ If any of these are missing, tell the user to add them to `~/.secrets`. The API

## Ports

- **Web dev server** (ShapeShift app): `localhost:3000`
- **Web dev server** (ShapeShift app): `localhost:3000` (or `$PORTLESS_URL` if using Portless, e.g. `http://<branch>.web.localhost:1355`)
- **qabot API/dashboard**: `localhost:8080` (dev) or deployed URL

**Portless note:** If the dev server is running via Portless, `PORTLESS_URL` is set automatically (e.g. `http://feat-x.web.localhost:1355`). The qabot profile stores wallet state per-origin, so each Portless origin is separate from `localhost:3000` - import the wallet once per new origin.

## Modes

### Interactive Mode (no fixture provided)
Expand Down Expand Up @@ -115,17 +117,39 @@ $AB --headed open <url>
agent-browser --session qabot --profile ~/.agent-browser/profiles/qabot open <url>
```

The profile at `~/.agent-browser/profiles/qabot` stores the native wallet (IndexedDB, localStorage, cookies) per origin. Import the wallet once per origin in headed mode, then reuse.
The profile at `~/.agent-browser/profiles/qabot` stores the native wallet (IndexedDB, localStorage, cookies) per origin. Import the wallet once per origin, then reuse.

First time setup per origin (headed, import wallet manually):
First-time setup per origin (keystore import - works headless):
```bash
agent-browser --session qabot --profile ~/.agent-browser/profiles/qabot --headed open <url>
# Import the native wallet, set password to $NATIVE_WALLET_PASSWORD, close.
# Subsequent runs reuse the persisted profile.
agent-browser --session qabot --profile ~/.agent-browser/profiles/qabot open <url>
```

Only use `--headed` if the user explicitly wants to import via seed phrase (which requires visual interaction). Keystore import is fully automatable headless.

**Keystore import flow** (when no native wallet exists for the origin):

There should be a keystore file on the Desktop (e.g. `thorswap-keystore*.txt` or similar). The exact filename may change - look for a keystore/json file on `~/Desktop/`.

1. Click "Connect Wallet" button (use JS eval if click times out):
`eval "document.querySelectorAll('button').forEach(b => { if(b.textContent.includes('Connect Wallet')) b.click() })"`
2. Click "Import existing"
3. Click "Keystore" (the "Import Keystore File" option)
4. Upload the keystore file to the hidden file input:
`upload "input[type=file]" "/Users/gomes/Desktop/<keystore-filename>"`
5. Fill the keystore password:
`fill "input[placeholder*=Password]" "$NATIVE_WALLET_PASSWORD"`
6. Click "Import Keystore"
7. On the "Create a New Password" screen:
- Fill nickname: `fill "input[placeholder*=nickname]" "test"`
- Fill password: `fill "input[placeholder*='Enter Password']" "$NATIVE_WALLET_PASSWORD"`
- Fill confirm: `fill "input[placeholder*='Confirm Password']" "$NATIVE_WALLET_PASSWORD"`
- Click "Next"
8. Skip onboarding carousel if shown
9. Wallet "test" should appear in top-right. Subsequent runs reuse the persisted profile.

Origins where the wallet has been imported:
- `http://localhost:3000` (local dev)
- `http://localhost:3000` (local dev, legacy)
- `http://<branch>.web.localhost:1355` (local dev via Portless - origin varies per branch, e.g. `develop.web.localhost:1355`)
- `https://gome.shapeshift.com` (gome staging)
- `https://release.shapeshift.com` (release staging)

Expand Down Expand Up @@ -260,7 +284,8 @@ When you encounter what looks like a bug, **don't just report it — investigate
```bash
source ~/.secrets
QABOT="${QABOT_URL:-http://localhost:8080}"
BASE_URL="${BASE_URL:-http://localhost:3000}"
# PORTLESS_URL is set automatically by Portless (e.g. http://develop.web.localhost:1355)
BASE_URL="${PORTLESS_URL:-${BASE_URL:-http://localhost:3000}}"
```

All write requests use:
Expand Down Expand Up @@ -319,23 +344,29 @@ Use **read-only git operations only** (fetch, rev-parse) - NEVER switch branches
GITHUB_REPO="shapeshift/web"

# Origin-to-branch mapping (CloudFlare Pages deployments):
# localhost:3000 → local branch (detected from dev server process)
# gome.shapeshift.com → gome
# release.shapeshift.com → release
# develop.shapeshift.com → develop
# app.shapeshift.com → main
# neo.shapeshift.com → neo
# localhost:3000 → local branch (detected from dev server process)
# *.web.localhost:1355 → local branch (Portless, detected from dev process)
# gome.shapeshift.com → gome
# release.shapeshift.com → release
# develop.shapeshift.com → develop
# app.shapeshift.com → main
# neo.shapeshift.com → neo

if [[ "$BASE_URL" == *"localhost"* ]]; then
# Local dev: detect web repo from the process actually serving port 3000
# This handles worktrees correctly (main repo vs .worktrees/qabot etc.)
DEV_PID=$(lsof -i :3000 -sTCP:LISTEN -n -P -t 2>/dev/null | head -1)
# Local dev: detect web repo from the process serving the dev server
# Try Portless proxy (1355) first, then direct port (3000), then any vite process
DEV_PID=$(lsof -i :1355 -sTCP:LISTEN -n -P -t 2>/dev/null | head -1)
if [ -z "$DEV_PID" ]; then
DEV_PID=$(lsof -i :3000 -sTCP:LISTEN -n -P -t 2>/dev/null | head -1)
fi
if [ -z "$DEV_PID" ]; then
DEV_PID=$(pgrep -f "vite.*--port" 2>/dev/null | head -1)
fi
if [ -n "$DEV_PID" ]; then
WEB_REPO=$(lsof -p "$DEV_PID" 2>/dev/null | awk '/cwd/{print $NF}')
fi
# Fallback: infer from context (check WEB_REPO env var, or ask the user)
if [ -z "$WEB_REPO" ]; then
echo "ERROR: Could not detect web repo from port 3000. Set WEB_REPO env var." >&2
echo "ERROR: Could not detect web repo. Set WEB_REPO env var." >&2
exit 1
fi
BRANCH=$(git -C "$WEB_REPO" rev-parse --abbrev-ref HEAD)
Expand Down
4 changes: 4 additions & 0 deletions .claude/test-scenarios/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ Tests for specific bugs that were fixed:
/test-agent maintenance
```

### Portless Support

All test scenarios reference `${PORTLESS_URL:-http://localhost:3000}` for the dev server URL. When using Portless, `PORTLESS_URL` is set automatically (e.g. `http://feat-x.web.localhost:1355`). Without Portless, everything defaults to `http://localhost:3000`.

### Manual Testing

Each scenario file contains:
Expand Down
2 changes: 1 addition & 1 deletion .claude/test-scenarios/TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Prerequisites

- Dev server running on `localhost:3000`
- Dev server running on `localhost:3000` (or `$PORTLESS_URL` if using Portless)
- [Other prerequisite 1]
- [Other prerequisite 2]
- [Required wallet state, test data, etc.]
Expand Down
4 changes: 2 additions & 2 deletions .claude/test-scenarios/chain-integration-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This template provides a complete testing workflow for validating new chain inte
## Prerequisites

### Environment
- **Application:** ShapeShift Web running locally (`http://localhost:3000`)
- **Application:** ShapeShift Web running locally (`${PORTLESS_URL:-http://localhost:3000}`)
- **Wallet:** Native ShapeShift wallet with password access
- **Test Data:** Existing holdings on the target chain (for account derivation testing)

Expand All @@ -38,7 +38,7 @@ Before starting, gather:

#### 1.1 Access Manage Accounts Modal
**Steps:**
1. Navigate to `http://localhost:3000` (or your test environment)
1. Navigate to `${PORTLESS_URL:-http://localhost:3000}` (or your test environment)
2. Ensure wallet is connected and unlocked
3. Click wallet button (top right corner)
4. Click three-dot menu icon
Expand Down
4 changes: 2 additions & 2 deletions .claude/test-scenarios/critical/asset-swap-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Prerequisites

- Dev server running on `localhost:3000`
- Dev server running on `localhost:3000` (or `$PORTLESS_URL` if using Portless)
- Wallet connected with test funds
- Test wallet should have:
- Small amount of ETH for gas
Expand All @@ -27,7 +27,7 @@
// Navigate to trade
browser_click({ element: "Trade navigation link", ref: "..." })
// OR
browser_navigate({ url: "http://localhost:3000/trade" })
browser_navigate({ url: "${PORTLESS_URL:-http://localhost:3000}/#/trade" })
```

**Validation Points**:
Expand Down
4 changes: 2 additions & 2 deletions .claude/test-scenarios/critical/wallet-connection-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

## Prerequisites

- Dev server running on `localhost:3000`
- Dev server running on `localhost:3000` (or `$PORTLESS_URL` if using Portless)
- Browser with MetaMask extension installed (or ability to test without actual wallet)
- No wallet currently connected

## Test Steps

### 1. Navigate to Application

**Action**: Open browser and navigate to `http://localhost:3000`
**Action**: Open browser and navigate to `${PORTLESS_URL:-http://localhost:3000}`
**Expected Result**: Application loads successfully, showing "Connect Wallet" button

**Validation Points**:
Expand Down
4 changes: 2 additions & 2 deletions .claude/test-scenarios/feature-discovery-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Start by navigating to the application and capturing the main navigation structu
```

**Steps**:
1. Navigate to `http://localhost:3000`
1. Navigate to `${PORTLESS_URL:-http://localhost:3000}`
2. Take snapshot of initial page
3. Document main navigation items
4. Document visible features/sections
Expand Down Expand Up @@ -272,7 +272,7 @@ Use browser MCP to automate discovery:

async function discoverFeatures() {
// 1. Navigate to home
await browser_navigate({ url: 'http://localhost:3000' })
await browser_navigate({ url: process.env.PORTLESS_URL || 'http://localhost:3000' })

// 2. Take snapshot
const homeSnapshot = await browser_snapshot()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

## Prerequisites

- Dev server running on `localhost:3000`
- Dev server running on `localhost:3000` (or `$PORTLESS_URL` if using Portless)
- Clean browser session (no cached flags)
- Knowledge of active feature flags in codebase

Expand All @@ -21,8 +21,8 @@

**Browser MCP Command**:
```javascript
// Navigate to home
browser_navigate({ url: "http://localhost:3000" })
// Navigate to home (use PORTLESS_URL or localhost:3000)
browser_navigate({ url: "${PORTLESS_URL:-http://localhost:3000}" })

// Open settings modal (click settings icon)
browser_click({ element: "Settings button", ref: "..." })
Expand All @@ -31,7 +31,7 @@ browser_click({ element: "Settings button", ref: "..." })
// (This is the secret gesture to access /flags)
```

**Alternative**: Navigate directly to `http://localhost:3000/flags`
**Alternative**: Navigate directly to `${PORTLESS_URL:-http://localhost:3000}/flags`

**Validation Points**:
- [ ] Feature flags panel accessible
Expand Down
2 changes: 1 addition & 1 deletion .claude/test-scenarios/markets-discovery-exploration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
## Test Configuration

### Test Environment
- **Application URL:** `http://localhost:3000/#/markets/recommended`
- **Application URL:** `${PORTLESS_URL:-http://localhost:3000}/#/markets/recommended`
- **Wallet Required:** No (browse mode)
- **Network:** Any

Expand Down
2 changes: 1 addition & 1 deletion .claude/test-scenarios/swap-eth-to-btc-same-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
**Action:** Navigate to trade page and configure swap pair

**Steps:**
1. Open ShapeShift at `http://localhost:3000/#/trade`
1. Open ShapeShift at `${PORTLESS_URL:-http://localhost:3000}/#/trade`
2. Ensure wallet is connected
3. Select ETH as source asset
4. Verify Ethereum is source chain
Expand Down
2 changes: 1 addition & 1 deletion .claude/test-scenarios/swapper-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Test Environment
- **Date**: 2025-01-18
- **Wallet**: Native wallet "awdaw" (password: qwerty123)
- **Dev Server**: localhost:3000
- **Dev Server**: localhost:3000 (or `$PORTLESS_URL` if using Portless)

## Overview

Expand Down
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ VITE_SEI_NODE_URL=https://evm-rpc.sei-apis.com
VITE_THORCHAIN_NODE_URL=https://api.thorchain.shapeshift.com/lcd
VITE_MAYACHAIN_NODE_URL=https://api.mayachain.shapeshift.com/lcd
VITE_SOLANA_NODE_URL=https://api.solana.shapeshift.com/api/v1/jsonrpc
VITE_JITO_BLOCK_ENGINE_URL=https://mainnet.block-engine.jito.wtf
VITE_STARKNET_NODE_URL=https://rpc.starknet.lava.build
VITE_TRON_NODE_URL=https://api.trongrid.io
VITE_NEAR_NODE_URL=https://rpc.mainnet.near.org
Expand Down Expand Up @@ -378,3 +379,6 @@ VITE_USERBACK_TOKEN=A-3gHopRTd55QqxXGsJd0XLVVG3
# agentic chat
VITE_FEATURE_AGENTIC_CHAT=false
VITE_AGENTIC_SERVER_BASE_URL=https://shapeshiftossagentic-server-production.up.railway.app

# MetaMask native multichain (BTC/SOL without snaps)
VITE_FEATURE_MM_NATIVE_MULTICHAIN=false
5 changes: 4 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ VITE_SEI_NODE_URL=https://evm-rpc.sei-apis.com
VITE_THORCHAIN_NODE_URL=https://dev-api.thorchain.shapeshift.com/lcd
VITE_MAYACHAIN_NODE_URL=https://dev-api.mayachain.shapeshift.com/lcd
VITE_SOLANA_NODE_URL=https://dev-api.solana.shapeshift.com/api/v1/jsonrpc
VITE_JITO_BLOCK_ENGINE_URL=https://mainnet.block-engine.jito.wtf
VITE_STARKNET_NODE_URL=https://rpc.starknet.lava.build
VITE_TRON_NODE_URL=https://api.trongrid.io

Expand All @@ -106,10 +107,11 @@ VITE_FEATURE_SWAPPER_FIAT_RAMPS=true

# Webservices
VITE_FEATURE_NOTIFICATIONS_WEBSERVICES=true
# Remote dev servers (default - works for all developers)
VITE_SWAPS_SERVER_URL=https://dev-api.swap-service.shapeshift.com
VITE_USER_SERVER_URL=https://dev-api.user-service.shapeshift.com
VITE_NOTIFICATIONS_SERVER_URL=https://dev-api.notifications-service.shapeshift.com
# Turn those on if you use local development instead of our railway instance
# Local development via Vite proxy (uncomment to use localhost backend)
# VITE_SWAPS_SERVER_URL=/swaps-api
# VITE_USER_SERVER_URL=/user-api
# VITE_NOTIFICATIONS_SERVER_URL=/notifications-api
Expand Down Expand Up @@ -147,5 +149,6 @@ VITE_FEATURE_YIELDS_PAGE=true
VITE_FEATURE_EARN_TAB=true
VITE_FEATURE_YIELD_MULTI_ACCOUNT=true
VITE_FEATURE_AGENTIC_CHAT=true
VITE_FEATURE_MM_NATIVE_MULTICHAIN=true
# VITE_AGENTIC_SERVER_BASE_URL=http://localhost:4111
VITE_AGENTIC_SERVER_BASE_URL=https://shapeshiftossagentic-server-production.up.railway.app
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ VITE_BASE_NODE_URL=https://api.base.shapeshift.com/api/v1/jsonrpc
VITE_THORCHAIN_NODE_URL=https://api.thorchain.shapeshift.com/lcd
VITE_MAYACHAIN_NODE_URL=https://api.mayachain.shapeshift.com/lcd
VITE_SOLANA_NODE_URL=https://api.solana.shapeshift.com/api/v1/jsonrpc
VITE_JITO_BLOCK_ENGINE_URL=https://mainnet.block-engine.jito.wtf

# midgard
VITE_THORCHAIN_MIDGARD_URL=https://api.thorchain.shapeshift.com/midgard/v2
Expand Down
Loading
Loading