Skip to content

Commit c8248b7

Browse files
Merge remote-tracking branch 'origin/main' into injective
# Conflicts: # .github/workflows/ci.yml # next.config.js # package.json # pnpm-lock.yaml # src/components/layout/AppLayout.tsx # src/components/nav/Footer.tsx # src/consts/chains.ts # src/consts/config.ts # src/consts/links.ts # src/features/tokens/types.ts # src/features/tokens/utils.test.ts # src/features/tokens/utils.ts # src/features/transfer/TransferTokenForm.tsx # src/features/transfer/fees.test.ts # src/features/transfer/fees.ts # src/features/transfer/maxAmount.ts # src/features/transfer/useFeeQuotes.ts # src/features/transfer/useTokenTransfer.ts
2 parents 7be8795 + 9b994ee commit c8248b7

36 files changed

+2328
-34
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: claude-review
3+
description: Review code changes using Hyperlane Warp UI coding standards. Use when reviewing PRs, checking your own changes, or doing self-review before committing.
4+
---
5+
6+
# Code Review Skill
7+
8+
Use this skill to review code changes against Hyperlane Warp UI standards.
9+
10+
## When to Use
11+
12+
- Before committing changes (self-review)
13+
- When asked to review a PR or diff
14+
- To check if changes follow project patterns
15+
16+
## Instructions
17+
18+
Read and apply the guidelines from `.github/prompts/code-review.md` to review the code changes.
19+
20+
Security issues should use `/claude-security-review` instead.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
name: claude-security-review
3+
description: Security-focused review for frontend/Web3 code. Use for XSS, wallet security, CSP, and dependency checks.
4+
---
5+
6+
# Security Review Skill
7+
8+
Use this skill for security-focused code review of frontend Web3 code.
9+
10+
## When to Use
11+
12+
- Reviewing wallet integration code
13+
- Checking for XSS vulnerabilities
14+
- CSP header changes
15+
- Dependency updates
16+
17+
## Instructions
18+
19+
Read and apply the security guidelines from `.github/prompts/security-scan.md` to review the code changes.
20+
21+
Report findings with severity ratings (Critical/High/Medium/Low/Informational) and suggested fixes.

.github/prompts/code-review.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Review this pull request. Focus on:
2+
3+
## Code Quality
4+
5+
- Logic errors and potential bugs
6+
- Error handling and edge cases
7+
- Code clarity and maintainability
8+
- Adherence to existing patterns in the codebase
9+
- **Use existing utilities** - Search codebase before adding new helpers
10+
- **Prefer `??` over `||`** - Preserves zero/empty string as valid values
11+
12+
## Architecture
13+
14+
- Consistency with existing architecture patterns
15+
- Breaking changes or backward compatibility issues
16+
- API contract changes
17+
- **Deduplicate** - Move repeated code/types to shared files
18+
- **Extract utilities** - Shared functions belong in utils packages
19+
20+
## Testing
21+
22+
- Test coverage for new/modified code
23+
- Edge cases that should be tested
24+
- **New utility functions need unit tests**
25+
26+
## Performance
27+
28+
- Unnecessary re-renders or computations
29+
- Bundle size impact of new dependencies
30+
31+
## Frontend-Specific
32+
33+
- **Use existing utilities** - Check `src/utils/` before adding (normalizeAddress, etc.)
34+
- **Chain-aware addresses** - Only lowercase EVM hex; Solana/Cosmos are case-sensitive
35+
- **CSP updates required** - New external scripts/styles need `next.config.js` CSP updates
36+
- **Avoid floating promises** - In useEffect, use IIFE or separate async function
37+
- **Use useQuery refetch** - Don't reinvent; use built-in refetch from TanStack Query
38+
- **Flatten rendering logic** - Avoid nested if; use early returns instead
39+
- **Zustand patterns** - Follow existing store patterns in `src/features/store.ts`
40+
- **Constants outside functions** - Move config/constants outside component functions
41+
42+
Provide actionable feedback with specific line references.
43+
Be concise. For minor style issues, group them together.
44+
Security issues are handled by a separate dedicated review.

.github/prompts/security-scan.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Frontend Security Focus Areas
2+
3+
This is a Web3 frontend application. Pay special attention to:
4+
5+
### XSS & Content Security
6+
- Input sanitization before rendering user data
7+
- Dangerous patterns: dangerouslySetInnerHTML, eval(), innerHTML
8+
- URL validation (javascript: protocol, data: URLs)
9+
- CSP headers and inline script risks
10+
11+
### Web3 Wallet Security
12+
- Blind signature attacks (signing data without user understanding)
13+
- Transaction simulation before signing
14+
- Clear message display before signature requests
15+
- Proper origin/domain verification for wallet connections
16+
- **Chain-aware address validation** - EVM hex can lowercase; Solana base58/Cosmos bech32 are case-sensitive
17+
- **Don't collapse addresses** - Normalizing non-EVM addresses can create security issues
18+
19+
### Dependency & Supply Chain
20+
- Known vulnerabilities in dependencies
21+
- Malicious packages, typosquatting
22+
- Outdated critical security packages
23+
24+
### API & Token Security
25+
- CORS configuration
26+
- Token storage (avoid localStorage for sensitive tokens)
27+
- API key exposure in client-side code
28+
29+
### Private Key Handling
30+
- NEVER expose private keys client-side
31+
- Check for hardcoded keys or mnemonics
32+
- Wallet connection patterns should not request keys
33+
34+
### Content Security Policy
35+
- New external resources (scripts, styles, frames) need CSP header updates
36+
- Check `next.config.js` for script-src, style-src, connect-src, frame-src
37+
- Third-party integrations (Intercom, analytics, wallets) need explicit allowlisting
38+
- Test with CSP enabled in production mode

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ jobs:
1919
- uses: pnpm/action-setup@v4
2020
- uses: actions/setup-node@v6
2121
with:
22+
<<<<<<< HEAD
2223
node-version-file: 'package.json'
24+
=======
25+
node-version-file: '.nvmrc'
26+
>>>>>>> origin/main
2327

2428
- name: Get pnpm store directory
2529
id: pnpm-store
@@ -52,7 +56,11 @@ jobs:
5256
- uses: pnpm/action-setup@v4
5357
- uses: actions/setup-node@v6
5458
with:
59+
<<<<<<< HEAD
5560
node-version-file: 'package.json'
61+
=======
62+
node-version-file: '.nvmrc'
63+
>>>>>>> origin/main
5664

5765
- name: Get pnpm store directory
5866
id: pnpm-store
@@ -83,7 +91,11 @@ jobs:
8391
- uses: pnpm/action-setup@v4
8492
- uses: actions/setup-node@v6
8593
with:
94+
<<<<<<< HEAD
8695
node-version-file: 'package.json'
96+
=======
97+
node-version-file: '.nvmrc'
98+
>>>>>>> origin/main
8799

88100
- name: Get pnpm store directory
89101
id: pnpm-store
@@ -118,7 +130,11 @@ jobs:
118130
- uses: pnpm/action-setup@v4
119131
- uses: actions/setup-node@v6
120132
with:
133+
<<<<<<< HEAD
121134
node-version-file: 'package.json'
135+
=======
136+
node-version-file: '.nvmrc'
137+
>>>>>>> origin/main
122138

123139
- name: Get pnpm store directory
124140
id: pnpm-store
@@ -147,7 +163,11 @@ jobs:
147163
- uses: pnpm/action-setup@v4
148164
- uses: actions/setup-node@v6
149165
with:
166+
<<<<<<< HEAD
150167
node-version-file: 'package.json'
168+
=======
169+
node-version-file: '.nvmrc'
170+
>>>>>>> origin/main
151171

152172
- name: Get pnpm store directory
153173
id: pnpm-store
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened, ready_for_review]
6+
pull_request_review_comment:
7+
types: [created]
8+
issue_comment:
9+
types: [created]
10+
11+
concurrency:
12+
group: claude-review-${{ github.event.pull_request.number || github.event.issue.number }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
code-review:
17+
if: |
18+
(
19+
github.event_name == 'issue_comment' &&
20+
github.event.issue.pull_request &&
21+
contains(github.event.comment.body, '@claude review') &&
22+
(
23+
github.event.comment.author_association == 'MEMBER' ||
24+
github.event.comment.author_association == 'OWNER' ||
25+
github.event.comment.author_association == 'COLLABORATOR'
26+
)
27+
) ||
28+
(
29+
github.event_name == 'pull_request' &&
30+
contains(join(github.event.pull_request.labels.*.name, ','), 'claude-review') &&
31+
github.event.pull_request.head.repo.full_name == github.repository
32+
)
33+
runs-on: ubuntu-latest
34+
timeout-minutes: 15
35+
permissions:
36+
contents: read
37+
pull-requests: write
38+
issues: write
39+
id-token: write
40+
steps:
41+
- name: Get PR SHA
42+
id: pr-sha
43+
uses: actions/github-script@v7
44+
with:
45+
script: |
46+
if (context.eventName === 'issue_comment') {
47+
const { data: pr } = await github.rest.pulls.get({
48+
owner: context.repo.owner,
49+
repo: context.repo.repo,
50+
pull_number: context.issue.number
51+
});
52+
core.setOutput('head_sha', pr.head.sha);
53+
} else {
54+
core.setOutput('head_sha', context.payload.pull_request.head.sha);
55+
}
56+
57+
- name: Checkout repository
58+
uses: actions/checkout@v6
59+
with:
60+
ref: ${{ steps.pr-sha.outputs.head_sha }}
61+
fetch-depth: 0
62+
63+
- name: Read code review prompt
64+
id: prompt
65+
run: |
66+
{
67+
echo 'content<<EOF'
68+
cat .github/prompts/code-review.md
69+
echo 'EOF'
70+
} >> $GITHUB_OUTPUT
71+
72+
- name: Run Claude Code Review
73+
uses: anthropics/claude-code-action@v1
74+
with:
75+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
76+
prompt: ${{ steps.prompt.outputs.content }}
77+
track_progress: true
78+
use_sticky_comment: true
79+
claude_args: |
80+
--model claude-opus-4-5
81+
--max-turns 30
82+
83+
security-review:
84+
if: |
85+
(
86+
github.event_name == 'pull_request' &&
87+
!github.event.pull_request.draft &&
88+
github.event.pull_request.head.repo.full_name == github.repository
89+
) ||
90+
(
91+
github.event_name == 'issue_comment' &&
92+
github.event.issue.pull_request &&
93+
contains(github.event.comment.body, '@claude security') &&
94+
(
95+
github.event.comment.author_association == 'MEMBER' ||
96+
github.event.comment.author_association == 'OWNER' ||
97+
github.event.comment.author_association == 'COLLABORATOR'
98+
)
99+
)
100+
runs-on: ubuntu-latest
101+
timeout-minutes: 20
102+
permissions:
103+
contents: read
104+
pull-requests: write
105+
issues: write
106+
id-token: write
107+
steps:
108+
- name: Get PR SHA
109+
id: pr-sha
110+
uses: actions/github-script@v7
111+
with:
112+
script: |
113+
if (context.eventName === 'issue_comment') {
114+
const { data: pr } = await github.rest.pulls.get({
115+
owner: context.repo.owner,
116+
repo: context.repo.repo,
117+
pull_number: context.issue.number
118+
});
119+
core.setOutput('head_sha', pr.head.sha);
120+
} else {
121+
core.setOutput('head_sha', context.payload.pull_request.head.sha);
122+
}
123+
124+
- name: Checkout repository
125+
uses: actions/checkout@v6
126+
with:
127+
ref: ${{ steps.pr-sha.outputs.head_sha }}
128+
fetch-depth: 2
129+
130+
- name: Run Claude Security Review
131+
uses: anthropics/claude-code-security-review@25e460eb0a12077f0c6a1934d5dbae2f50785dda
132+
with:
133+
claude-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
134+
comment-pr: true
135+
upload-results: true
136+
exclude-directories: 'node_modules,dist,.next,coverage,cache'
137+
claudecode-timeout: '15'
138+
claude-model: claude-opus-4-5
139+
custom-security-scan-instructions: '.github/prompts/security-scan.md'
140+
141+
interactive:
142+
if: |
143+
(
144+
github.event_name == 'issue_comment' &&
145+
github.event.issue.pull_request &&
146+
contains(github.event.comment.body, '@claude') &&
147+
!contains(github.event.comment.body, '@claude review') &&
148+
!contains(github.event.comment.body, '@claude security') &&
149+
(
150+
github.event.comment.author_association == 'MEMBER' ||
151+
github.event.comment.author_association == 'OWNER' ||
152+
github.event.comment.author_association == 'COLLABORATOR'
153+
)
154+
) ||
155+
(
156+
github.event_name == 'pull_request_review_comment' &&
157+
github.event.pull_request.head.repo.full_name == github.repository &&
158+
contains(github.event.comment.body, '@claude') &&
159+
!contains(github.event.comment.body, '@claude security') &&
160+
(
161+
github.event.comment.author_association == 'MEMBER' ||
162+
github.event.comment.author_association == 'OWNER' ||
163+
github.event.comment.author_association == 'COLLABORATOR'
164+
)
165+
)
166+
runs-on: ubuntu-latest
167+
timeout-minutes: 15
168+
permissions:
169+
contents: read
170+
pull-requests: write
171+
issues: write
172+
id-token: write
173+
steps:
174+
- name: Get PR SHA
175+
id: pr-sha
176+
uses: actions/github-script@v7
177+
with:
178+
script: |
179+
let prNumber;
180+
if (context.eventName === 'issue_comment') {
181+
prNumber = context.issue.number;
182+
} else if (context.eventName === 'pull_request_review_comment') {
183+
prNumber = context.payload.pull_request.number;
184+
}
185+
if (prNumber) {
186+
const { data: pr } = await github.rest.pulls.get({
187+
owner: context.repo.owner,
188+
repo: context.repo.repo,
189+
pull_number: prNumber
190+
});
191+
core.setOutput('head_sha', pr.head.sha);
192+
}
193+
194+
- name: Checkout repository
195+
uses: actions/checkout@v6
196+
with:
197+
ref: ${{ steps.pr-sha.outputs.head_sha || github.sha }}
198+
fetch-depth: 0
199+
200+
- name: Run Claude Code Assistant
201+
uses: anthropics/claude-code-action@v1
202+
with:
203+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
204+
track_progress: true
205+
use_sticky_comment: true
206+
claude_args: |
207+
--model claude-sonnet-4-5
208+
--max-turns 20

0 commit comments

Comments
 (0)